Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceOlddiv.c
1// Copyright 2025, Kay Hayen, mailto:kay.hayen@gmail.com find license text at end of file
2
3/* WARNING, this code is GENERATED. Modify the template HelperOperationInplace.c.j2 instead! */
4
5/* This file is included from another C file, help IDEs to still parse it on its own. */
6#ifdef __IDE_ONLY__
7#include "nuitka/prelude.h"
8#endif
9
10/* C helpers for type in-place "/" (OLDDIV) operations */
11
12#if PYTHON_VERSION < 0x300
13/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
14static inline bool _INPLACE_OPERATION_OLDDIV_INT_INT(PyObject **operand1, PyObject *operand2) {
15 assert(operand1); // Pointer must be non-null.
16
17 CHECK_OBJECT(*operand1);
18 assert(PyInt_CheckExact(*operand1));
19 CHECK_OBJECT(operand2);
20 assert(PyInt_CheckExact(operand2));
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 if (unlikely(b == 0)) {
44 PyThreadState *tstate = PyThreadState_GET();
45
46 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "integer division or modulo by zero");
47 goto exit_result_exception;
48 }
49
50 /* TODO: Isn't this a very specific value only, of which we could
51 * hardcode the constant result. Not sure how well the C compiler
52 * optimizes UNARY_NEG_WOULD_OVERFLOW to this, but dividing by
53 * -1 has to be rare anyway.
54 */
55
56 if (likely(b != -1 || !UNARY_NEG_WOULD_OVERFLOW(a))) {
57 long a_div_b = a / b;
58 long a_mod_b = (long)(a - (unsigned long)a_div_b * b);
59
60 if (a_mod_b && (b ^ a_mod_b) < 0) {
61 a_mod_b += b;
62 a_div_b -= 1;
63 }
64
65 clong_result = a_div_b;
66 goto exit_result_ok_clong;
67 }
68
69 {
70 PyObject *operand1_object = *operand1;
71 PyObject *operand2_object = operand2;
72
73 PyObject *r = PyLong_Type.tp_as_number->nb_divide(operand1_object, operand2_object);
74 assert(r != Py_NotImplemented);
75
76 obj_result = r;
77 goto exit_result_object;
78 }
79
80exit_result_ok_clong:
81
82 // We got an object handed, that we have to release.
83 Py_DECREF(*operand1);
84
85 // That's our return value then. As we use a dedicated variable, it's
86 // OK that way.
87 *operand1 = Nuitka_PyInt_FromLong(clong_result);
88 goto exit_result_ok;
89
90exit_result_object:
91 if (unlikely(obj_result == NULL)) {
92 goto exit_result_exception;
93 }
94 // We got an object handed, that we have to release.
95 Py_DECREF(*operand1);
96
97 *operand1 = obj_result;
98 goto exit_result_ok;
99
100exit_result_ok:
101 return true;
102
103exit_result_exception:
104 return false;
105}
106
107bool INPLACE_OPERATION_OLDDIV_INT_INT(PyObject **operand1, PyObject *operand2) {
108 return _INPLACE_OPERATION_OLDDIV_INT_INT(operand1, operand2);
109}
110#endif
111
112#if PYTHON_VERSION < 0x300
113/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
114static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
115 PyTypeObject *type1 = Py_TYPE(*operand1);
116
117#if defined(_MSC_VER)
118#pragma warning(push)
119#pragma warning(disable : 4101)
120#endif
121 NUITKA_MAY_BE_UNUSED bool cbool_result;
122 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
123#if defined(_MSC_VER)
124#pragma warning(pop)
125#endif
126
127 binaryfunc islot =
128 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_divide : NULL;
129
130 if (islot != NULL) {
131 PyObject *x = islot(*operand1, operand2);
132
133 if (x != Py_NotImplemented) {
134 obj_result = x;
135 goto exit_inplace_result_object;
136 }
137
138 Py_DECREF_IMMORTAL(x);
139 }
140
141 {
142 binaryfunc slot1 =
143 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_divide : NULL;
144 binaryfunc slot2 = NULL;
145
146 if (!(type1 == &PyInt_Type)) {
147 // Different types, need to consider second value slot.
148
149 slot2 = PyInt_Type.tp_as_number->nb_divide;
150
151 if (slot1 == slot2) {
152 slot2 = NULL;
153 }
154 }
155
156 if (slot1 != NULL) {
157 PyObject *x = slot1(*operand1, operand2);
158
159 if (x != Py_NotImplemented) {
160 obj_result = x;
161 goto exit_inplace_result_object;
162 }
163
164 Py_DECREF_IMMORTAL(x);
165 }
166
167 if (slot2 != NULL) {
168 PyObject *x = slot2(*operand1, operand2);
169
170 if (x != Py_NotImplemented) {
171 obj_result = x;
172 goto exit_inplace_result_object;
173 }
174
175 Py_DECREF_IMMORTAL(x);
176 }
177
178#if PYTHON_VERSION < 0x300
179 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
180 coercion c1 =
181 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
182
183 if (c1 != NULL) {
184 PyObject *coerced1 = *operand1;
185 PyObject *coerced2 = operand2;
186
187 int err = c1(&coerced1, &coerced2);
188
189 if (unlikely(err < 0)) {
190 goto exit_inplace_exception;
191 }
192
193 if (err == 0) {
194 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
195
196 if (likely(mv == NULL)) {
197 binaryfunc slot = mv->nb_divide;
198
199 if (likely(slot != NULL)) {
200 PyObject *x = slot(coerced1, coerced2);
201
202 Py_DECREF(coerced1);
203 Py_DECREF(coerced2);
204
205 obj_result = x;
206 goto exit_inplace_result_object;
207 }
208 }
209
210 // nb_coerce took a reference.
211 Py_DECREF(coerced1);
212 Py_DECREF(coerced2);
213 }
214 }
215 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
216
217 if (c2 != NULL) {
218 PyObject *coerced1 = *operand1;
219 PyObject *coerced2 = operand2;
220
221 int err = c2(&coerced2, &coerced1);
222
223 if (unlikely(err < 0)) {
224 goto exit_inplace_exception;
225 }
226
227 if (err == 0) {
228 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
229
230 if (likely(mv == NULL)) {
231 binaryfunc slot = mv->nb_divide;
232
233 if (likely(slot != NULL)) {
234 PyObject *x = slot(coerced1, coerced2);
235
236 Py_DECREF(coerced1);
237 Py_DECREF(coerced2);
238
239 obj_result = x;
240 goto exit_inplace_result_object;
241 }
242 }
243
244 // nb_coerce took a reference.
245 Py_DECREF(coerced1);
246 Py_DECREF(coerced2);
247 }
248 }
249 }
250#endif
251
252 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: '%s' and 'int'", type1->tp_name);
253 goto exit_inplace_exception;
254 }
255
256exit_inplace_result_object:
257 if (unlikely(obj_result == NULL)) {
258 return false;
259 }
260
261 // We got an object handed, that we have to release.
262 Py_DECREF(*operand1);
263
264 // That's our return value then. As we use a dedicated variable, it's
265 // OK that way.
266 *operand1 = obj_result;
267
268 return true;
269
270exit_inplace_exception:
271 return false;
272}
273static inline bool _INPLACE_OPERATION_OLDDIV_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
274 assert(operand1); // Pointer must be non-null.
275
276 CHECK_OBJECT(*operand1);
277 CHECK_OBJECT(operand2);
278 assert(PyInt_CheckExact(operand2));
279
280 PyTypeObject *type1 = Py_TYPE(*operand1);
281
282 if (type1 == &PyInt_Type) {
283 // return _BINARY_OPERATION_OLDDIV_INT_INT_INPLACE(operand1, operand2);
284
285 // Not every code path will make use of all possible results.
286#if defined(_MSC_VER)
287#pragma warning(push)
288#pragma warning(disable : 4101)
289#endif
290 NUITKA_MAY_BE_UNUSED bool cbool_result;
291 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
292 NUITKA_MAY_BE_UNUSED long clong_result;
293 NUITKA_MAY_BE_UNUSED double cfloat_result;
294#if defined(_MSC_VER)
295#pragma warning(pop)
296#endif
297
298 CHECK_OBJECT(*operand1);
299 assert(PyInt_CheckExact(*operand1));
300 CHECK_OBJECT(operand2);
301 assert(PyInt_CheckExact(operand2));
302
303 const long a = PyInt_AS_LONG(*operand1);
304 const long b = PyInt_AS_LONG(operand2);
305
306 if (unlikely(b == 0)) {
307 PyThreadState *tstate = PyThreadState_GET();
308
309 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "integer division or modulo by zero");
310 goto exit_result_exception;
311 }
312
313 /* TODO: Isn't this a very specific value only, of which we could
314 * hardcode the constant result. Not sure how well the C compiler
315 * optimizes UNARY_NEG_WOULD_OVERFLOW to this, but dividing by
316 * -1 has to be rare anyway.
317 */
318
319 if (likely(b != -1 || !UNARY_NEG_WOULD_OVERFLOW(a))) {
320 long a_div_b = a / b;
321 long a_mod_b = (long)(a - (unsigned long)a_div_b * b);
322
323 if (a_mod_b && (b ^ a_mod_b) < 0) {
324 a_mod_b += b;
325 a_div_b -= 1;
326 }
327
328 clong_result = a_div_b;
329 goto exit_result_ok_clong;
330 }
331
332 {
333 PyObject *operand1_object = *operand1;
334 PyObject *operand2_object = operand2;
335
336 PyObject *r = PyLong_Type.tp_as_number->nb_divide(operand1_object, operand2_object);
337 assert(r != Py_NotImplemented);
338
339 obj_result = r;
340 goto exit_result_object;
341 }
342
343 exit_result_ok_clong:
344
345 // We got an object handed, that we have to release.
346 Py_DECREF(*operand1);
347
348 // That's our return value then. As we use a dedicated variable, it's
349 // OK that way.
350 *operand1 = Nuitka_PyInt_FromLong(clong_result);
351 goto exit_result_ok;
352
353 exit_result_object:
354 if (unlikely(obj_result == NULL)) {
355 goto exit_result_exception;
356 }
357 // We got an object handed, that we have to release.
358 Py_DECREF(*operand1);
359
360 *operand1 = obj_result;
361 goto exit_result_ok;
362
363 exit_result_ok:
364 return true;
365
366 exit_result_exception:
367 return false;
368 }
369
370 return __INPLACE_OPERATION_OLDDIV_OBJECT_INT(operand1, operand2);
371}
372
373bool INPLACE_OPERATION_OLDDIV_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
374 return _INPLACE_OPERATION_OLDDIV_OBJECT_INT(operand1, operand2);
375}
376#endif
377
378#if PYTHON_VERSION < 0x300
379/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
380static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
381 PyTypeObject *type2 = Py_TYPE(operand2);
382
383#if defined(_MSC_VER)
384#pragma warning(push)
385#pragma warning(disable : 4101)
386#endif
387 NUITKA_MAY_BE_UNUSED bool cbool_result;
388 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
389#if defined(_MSC_VER)
390#pragma warning(pop)
391#endif
392
393 // No inplace number slot nb_inplace_divide available for this type.
394
395 {
396 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_divide;
397 binaryfunc slot2 = NULL;
398
399 if (!(&PyInt_Type == type2)) {
400 // Different types, need to consider second value slot.
401
402 slot2 =
403 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_divide : NULL;
404
405 if (slot1 == slot2) {
406 slot2 = NULL;
407 }
408 }
409
410 if (slot1 != NULL) {
411 if (slot2 != NULL) {
412 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
413 PyObject *x = slot2(*operand1, operand2);
414
415 if (x != Py_NotImplemented) {
416 obj_result = x;
417 goto exit_inplace_result_object;
418 }
419
420 Py_DECREF_IMMORTAL(x);
421 slot2 = NULL;
422 }
423 }
424
425 PyObject *x = slot1(*operand1, operand2);
426
427 if (x != Py_NotImplemented) {
428 obj_result = x;
429 goto exit_inplace_result_object;
430 }
431
432 Py_DECREF_IMMORTAL(x);
433 }
434
435 if (slot2 != NULL) {
436 PyObject *x = slot2(*operand1, operand2);
437
438 if (x != Py_NotImplemented) {
439 obj_result = x;
440 goto exit_inplace_result_object;
441 }
442
443 Py_DECREF_IMMORTAL(x);
444 }
445
446#if PYTHON_VERSION < 0x300
447 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
448 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
449
450 if (c1 != NULL) {
451 PyObject *coerced1 = *operand1;
452 PyObject *coerced2 = operand2;
453
454 int err = c1(&coerced1, &coerced2);
455
456 if (unlikely(err < 0)) {
457 goto exit_inplace_exception;
458 }
459
460 if (err == 0) {
461 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
462
463 if (likely(mv == NULL)) {
464 binaryfunc slot = mv->nb_divide;
465
466 if (likely(slot != NULL)) {
467 PyObject *x = slot(coerced1, coerced2);
468
469 Py_DECREF(coerced1);
470 Py_DECREF(coerced2);
471
472 obj_result = x;
473 goto exit_inplace_result_object;
474 }
475 }
476
477 // nb_coerce took a reference.
478 Py_DECREF(coerced1);
479 Py_DECREF(coerced2);
480 }
481 }
482 coercion c2 =
483 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
484
485 if (c2 != NULL) {
486 PyObject *coerced1 = *operand1;
487 PyObject *coerced2 = operand2;
488
489 int err = c2(&coerced2, &coerced1);
490
491 if (unlikely(err < 0)) {
492 goto exit_inplace_exception;
493 }
494
495 if (err == 0) {
496 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
497
498 if (likely(mv == NULL)) {
499 binaryfunc slot = mv->nb_divide;
500
501 if (likely(slot != NULL)) {
502 PyObject *x = slot(coerced1, coerced2);
503
504 Py_DECREF(coerced1);
505 Py_DECREF(coerced2);
506
507 obj_result = x;
508 goto exit_inplace_result_object;
509 }
510 }
511
512 // nb_coerce took a reference.
513 Py_DECREF(coerced1);
514 Py_DECREF(coerced2);
515 }
516 }
517 }
518#endif
519
520 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'int' and '%s'", type2->tp_name);
521 goto exit_inplace_exception;
522 }
523
524exit_inplace_result_object:
525 if (unlikely(obj_result == NULL)) {
526 return false;
527 }
528
529 // We got an object handed, that we have to release.
530 Py_DECREF(*operand1);
531
532 // That's our return value then. As we use a dedicated variable, it's
533 // OK that way.
534 *operand1 = obj_result;
535
536 return true;
537
538exit_inplace_exception:
539 return false;
540}
541static inline bool _INPLACE_OPERATION_OLDDIV_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
542 assert(operand1); // Pointer must be non-null.
543
544 CHECK_OBJECT(*operand1);
545 assert(PyInt_CheckExact(*operand1));
546 CHECK_OBJECT(operand2);
547
548 PyTypeObject *type2 = Py_TYPE(operand2);
549
550 if (&PyInt_Type == type2) {
551 // return _BINARY_OPERATION_OLDDIV_INT_INT_INPLACE(operand1, operand2);
552
553 // Not every code path will make use of all possible results.
554#if defined(_MSC_VER)
555#pragma warning(push)
556#pragma warning(disable : 4101)
557#endif
558 NUITKA_MAY_BE_UNUSED bool cbool_result;
559 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
560 NUITKA_MAY_BE_UNUSED long clong_result;
561 NUITKA_MAY_BE_UNUSED double cfloat_result;
562#if defined(_MSC_VER)
563#pragma warning(pop)
564#endif
565
566 CHECK_OBJECT(*operand1);
567 assert(PyInt_CheckExact(*operand1));
568 CHECK_OBJECT(operand2);
569 assert(PyInt_CheckExact(operand2));
570
571 const long a = PyInt_AS_LONG(*operand1);
572 const long b = PyInt_AS_LONG(operand2);
573
574 if (unlikely(b == 0)) {
575 PyThreadState *tstate = PyThreadState_GET();
576
577 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "integer division or modulo by zero");
578 goto exit_result_exception;
579 }
580
581 /* TODO: Isn't this a very specific value only, of which we could
582 * hardcode the constant result. Not sure how well the C compiler
583 * optimizes UNARY_NEG_WOULD_OVERFLOW to this, but dividing by
584 * -1 has to be rare anyway.
585 */
586
587 if (likely(b != -1 || !UNARY_NEG_WOULD_OVERFLOW(a))) {
588 long a_div_b = a / b;
589 long a_mod_b = (long)(a - (unsigned long)a_div_b * b);
590
591 if (a_mod_b && (b ^ a_mod_b) < 0) {
592 a_mod_b += b;
593 a_div_b -= 1;
594 }
595
596 clong_result = a_div_b;
597 goto exit_result_ok_clong;
598 }
599
600 {
601 PyObject *operand1_object = *operand1;
602 PyObject *operand2_object = operand2;
603
604 PyObject *r = PyLong_Type.tp_as_number->nb_divide(operand1_object, operand2_object);
605 assert(r != Py_NotImplemented);
606
607 obj_result = r;
608 goto exit_result_object;
609 }
610
611 exit_result_ok_clong:
612
613 // We got an object handed, that we have to release.
614 Py_DECREF(*operand1);
615
616 // That's our return value then. As we use a dedicated variable, it's
617 // OK that way.
618 *operand1 = Nuitka_PyInt_FromLong(clong_result);
619 goto exit_result_ok;
620
621 exit_result_object:
622 if (unlikely(obj_result == NULL)) {
623 goto exit_result_exception;
624 }
625 // We got an object handed, that we have to release.
626 Py_DECREF(*operand1);
627
628 *operand1 = obj_result;
629 goto exit_result_ok;
630
631 exit_result_ok:
632 return true;
633
634 exit_result_exception:
635 return false;
636 }
637
638 return __INPLACE_OPERATION_OLDDIV_INT_OBJECT(operand1, operand2);
639}
640
641bool INPLACE_OPERATION_OLDDIV_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
642 return _INPLACE_OPERATION_OLDDIV_INT_OBJECT(operand1, operand2);
643}
644#endif
645
646#if PYTHON_VERSION < 0x300
647/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LONG" to Python2 'long', Python3 'int'. */
648static inline bool _INPLACE_OPERATION_OLDDIV_LONG_LONG(PyObject **operand1, PyObject *operand2) {
649 assert(operand1); // Pointer must be non-null.
650
651 CHECK_OBJECT(*operand1);
652 assert(PyLong_CheckExact(*operand1));
653 CHECK_OBJECT(operand2);
654 assert(PyLong_CheckExact(operand2));
655
656 // Not every code path will make use of all possible results.
657#if defined(_MSC_VER)
658#pragma warning(push)
659#pragma warning(disable : 4101)
660#endif
661 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
662 NUITKA_MAY_BE_UNUSED long clong_result;
663#if defined(_MSC_VER)
664#pragma warning(pop)
665#endif
666
667 PyObject *x = PyLong_Type.tp_as_number->nb_divide(*operand1, operand2);
668 assert(x != Py_NotImplemented);
669
670 obj_result = x;
671 goto exit_result_object;
672
673exit_result_object:
674 if (unlikely(obj_result == NULL)) {
675 goto exit_result_exception;
676 }
677 // We got an object handed, that we have to release.
678 Py_DECREF(*operand1);
679 *operand1 = obj_result;
680 goto exit_result_ok;
681
682exit_result_ok:
683 return true;
684
685exit_result_exception:
686 return false;
687}
688
689bool INPLACE_OPERATION_OLDDIV_LONG_LONG(PyObject **operand1, PyObject *operand2) {
690 return _INPLACE_OPERATION_OLDDIV_LONG_LONG(operand1, operand2);
691}
692#endif
693
694#if PYTHON_VERSION < 0x300
695/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
696static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
697 PyTypeObject *type1 = Py_TYPE(*operand1);
698
699#if defined(_MSC_VER)
700#pragma warning(push)
701#pragma warning(disable : 4101)
702#endif
703 NUITKA_MAY_BE_UNUSED bool cbool_result;
704 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
705#if defined(_MSC_VER)
706#pragma warning(pop)
707#endif
708
709 binaryfunc islot =
710 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_divide : NULL;
711
712 if (islot != NULL) {
713 PyObject *x = islot(*operand1, operand2);
714
715 if (x != Py_NotImplemented) {
716 obj_result = x;
717 goto exit_inplace_result_object;
718 }
719
720 Py_DECREF_IMMORTAL(x);
721 }
722
723 {
724 binaryfunc slot1 =
725 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_divide : NULL;
726 binaryfunc slot2 = NULL;
727
728 if (!(type1 == &PyLong_Type)) {
729 // Different types, need to consider second value slot.
730
731 slot2 = PyLong_Type.tp_as_number->nb_divide;
732
733 if (slot1 == slot2) {
734 slot2 = NULL;
735 }
736 }
737
738 if (slot1 != NULL) {
739 PyObject *x = slot1(*operand1, operand2);
740
741 if (x != Py_NotImplemented) {
742 obj_result = x;
743 goto exit_inplace_result_object;
744 }
745
746 Py_DECREF_IMMORTAL(x);
747 }
748
749 if (slot2 != NULL) {
750 PyObject *x = slot2(*operand1, operand2);
751
752 if (x != Py_NotImplemented) {
753 obj_result = x;
754 goto exit_inplace_result_object;
755 }
756
757 Py_DECREF_IMMORTAL(x);
758 }
759
760#if PYTHON_VERSION < 0x300
761 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
762 coercion c1 =
763 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
764
765 if (c1 != NULL) {
766 PyObject *coerced1 = *operand1;
767 PyObject *coerced2 = operand2;
768
769 int err = c1(&coerced1, &coerced2);
770
771 if (unlikely(err < 0)) {
772 goto exit_inplace_exception;
773 }
774
775 if (err == 0) {
776 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
777
778 if (likely(mv == NULL)) {
779 binaryfunc slot = mv->nb_divide;
780
781 if (likely(slot != NULL)) {
782 PyObject *x = slot(coerced1, coerced2);
783
784 Py_DECREF(coerced1);
785 Py_DECREF(coerced2);
786
787 obj_result = x;
788 goto exit_inplace_result_object;
789 }
790 }
791
792 // nb_coerce took a reference.
793 Py_DECREF(coerced1);
794 Py_DECREF(coerced2);
795 }
796 }
797 coercion c2 = PyLong_Type.tp_as_number->nb_coerce;
798
799 if (c2 != NULL) {
800 PyObject *coerced1 = *operand1;
801 PyObject *coerced2 = operand2;
802
803 int err = c2(&coerced2, &coerced1);
804
805 if (unlikely(err < 0)) {
806 goto exit_inplace_exception;
807 }
808
809 if (err == 0) {
810 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
811
812 if (likely(mv == NULL)) {
813 binaryfunc slot = mv->nb_divide;
814
815 if (likely(slot != NULL)) {
816 PyObject *x = slot(coerced1, coerced2);
817
818 Py_DECREF(coerced1);
819 Py_DECREF(coerced2);
820
821 obj_result = x;
822 goto exit_inplace_result_object;
823 }
824 }
825
826 // nb_coerce took a reference.
827 Py_DECREF(coerced1);
828 Py_DECREF(coerced2);
829 }
830 }
831 }
832#endif
833
834#if PYTHON_VERSION < 0x300
835 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: '%s' and 'long'", type1->tp_name);
836#else
837 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: '%s' and 'int'", type1->tp_name);
838#endif
839 goto exit_inplace_exception;
840 }
841
842exit_inplace_result_object:
843 if (unlikely(obj_result == NULL)) {
844 return false;
845 }
846
847 // We got an object handed, that we have to release.
848 Py_DECREF(*operand1);
849
850 // That's our return value then. As we use a dedicated variable, it's
851 // OK that way.
852 *operand1 = obj_result;
853
854 return true;
855
856exit_inplace_exception:
857 return false;
858}
859static inline bool _INPLACE_OPERATION_OLDDIV_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
860 assert(operand1); // Pointer must be non-null.
861
862 CHECK_OBJECT(*operand1);
863 CHECK_OBJECT(operand2);
864 assert(PyLong_CheckExact(operand2));
865
866 PyTypeObject *type1 = Py_TYPE(*operand1);
867
868 if (type1 == &PyLong_Type) {
869 // return _BINARY_OPERATION_OLDDIV_LONG_LONG_INPLACE(operand1, operand2);
870
871 // Not every code path will make use of all possible results.
872#if defined(_MSC_VER)
873#pragma warning(push)
874#pragma warning(disable : 4101)
875#endif
876 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
877 NUITKA_MAY_BE_UNUSED long clong_result;
878#if defined(_MSC_VER)
879#pragma warning(pop)
880#endif
881
882 PyObject *x = PyLong_Type.tp_as_number->nb_divide(*operand1, operand2);
883 assert(x != Py_NotImplemented);
884
885 obj_result = x;
886 goto exit_result_object;
887
888 exit_result_object:
889 if (unlikely(obj_result == NULL)) {
890 goto exit_result_exception;
891 }
892 // We got an object handed, that we have to release.
893 Py_DECREF(*operand1);
894 *operand1 = obj_result;
895 goto exit_result_ok;
896
897 exit_result_ok:
898 return true;
899
900 exit_result_exception:
901 return false;
902 }
903
904 return __INPLACE_OPERATION_OLDDIV_OBJECT_LONG(operand1, operand2);
905}
906
907bool INPLACE_OPERATION_OLDDIV_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
908 return _INPLACE_OPERATION_OLDDIV_OBJECT_LONG(operand1, operand2);
909}
910#endif
911
912#if PYTHON_VERSION < 0x300
913/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
914static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
915 PyTypeObject *type2 = Py_TYPE(operand2);
916
917#if defined(_MSC_VER)
918#pragma warning(push)
919#pragma warning(disable : 4101)
920#endif
921 NUITKA_MAY_BE_UNUSED bool cbool_result;
922 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
923#if defined(_MSC_VER)
924#pragma warning(pop)
925#endif
926
927 // No inplace number slot nb_inplace_divide available for this type.
928
929 {
930 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_divide;
931 binaryfunc slot2 = NULL;
932
933 if (!(&PyLong_Type == type2)) {
934 // Different types, need to consider second value slot.
935
936 slot2 =
937 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_divide : NULL;
938
939 if (slot1 == slot2) {
940 slot2 = NULL;
941 }
942 }
943
944 if (slot1 != NULL) {
945 if (slot2 != NULL) {
946 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
947 PyObject *x = slot2(*operand1, operand2);
948
949 if (x != Py_NotImplemented) {
950 obj_result = x;
951 goto exit_inplace_result_object;
952 }
953
954 Py_DECREF_IMMORTAL(x);
955 slot2 = NULL;
956 }
957 }
958
959 PyObject *x = slot1(*operand1, operand2);
960
961 if (x != Py_NotImplemented) {
962 obj_result = x;
963 goto exit_inplace_result_object;
964 }
965
966 Py_DECREF_IMMORTAL(x);
967 }
968
969 if (slot2 != NULL) {
970 PyObject *x = slot2(*operand1, operand2);
971
972 if (x != Py_NotImplemented) {
973 obj_result = x;
974 goto exit_inplace_result_object;
975 }
976
977 Py_DECREF_IMMORTAL(x);
978 }
979
980#if PYTHON_VERSION < 0x300
981 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
982 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
983
984 if (c1 != NULL) {
985 PyObject *coerced1 = *operand1;
986 PyObject *coerced2 = operand2;
987
988 int err = c1(&coerced1, &coerced2);
989
990 if (unlikely(err < 0)) {
991 goto exit_inplace_exception;
992 }
993
994 if (err == 0) {
995 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
996
997 if (likely(mv == NULL)) {
998 binaryfunc slot = mv->nb_divide;
999
1000 if (likely(slot != NULL)) {
1001 PyObject *x = slot(coerced1, coerced2);
1002
1003 Py_DECREF(coerced1);
1004 Py_DECREF(coerced2);
1005
1006 obj_result = x;
1007 goto exit_inplace_result_object;
1008 }
1009 }
1010
1011 // nb_coerce took a reference.
1012 Py_DECREF(coerced1);
1013 Py_DECREF(coerced2);
1014 }
1015 }
1016 coercion c2 =
1017 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1018
1019 if (c2 != NULL) {
1020 PyObject *coerced1 = *operand1;
1021 PyObject *coerced2 = operand2;
1022
1023 int err = c2(&coerced2, &coerced1);
1024
1025 if (unlikely(err < 0)) {
1026 goto exit_inplace_exception;
1027 }
1028
1029 if (err == 0) {
1030 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1031
1032 if (likely(mv == NULL)) {
1033 binaryfunc slot = mv->nb_divide;
1034
1035 if (likely(slot != NULL)) {
1036 PyObject *x = slot(coerced1, coerced2);
1037
1038 Py_DECREF(coerced1);
1039 Py_DECREF(coerced2);
1040
1041 obj_result = x;
1042 goto exit_inplace_result_object;
1043 }
1044 }
1045
1046 // nb_coerce took a reference.
1047 Py_DECREF(coerced1);
1048 Py_DECREF(coerced2);
1049 }
1050 }
1051 }
1052#endif
1053
1054#if PYTHON_VERSION < 0x300
1055 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'long' and '%s'", type2->tp_name);
1056#else
1057 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'int' and '%s'", type2->tp_name);
1058#endif
1059 goto exit_inplace_exception;
1060 }
1061
1062exit_inplace_result_object:
1063 if (unlikely(obj_result == NULL)) {
1064 return false;
1065 }
1066
1067 // We got an object handed, that we have to release.
1068 Py_DECREF(*operand1);
1069
1070 // That's our return value then. As we use a dedicated variable, it's
1071 // OK that way.
1072 *operand1 = obj_result;
1073
1074 return true;
1075
1076exit_inplace_exception:
1077 return false;
1078}
1079static inline bool _INPLACE_OPERATION_OLDDIV_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
1080 assert(operand1); // Pointer must be non-null.
1081
1082 CHECK_OBJECT(*operand1);
1083 assert(PyLong_CheckExact(*operand1));
1084 CHECK_OBJECT(operand2);
1085
1086 PyTypeObject *type2 = Py_TYPE(operand2);
1087
1088 if (&PyLong_Type == type2) {
1089 // return _BINARY_OPERATION_OLDDIV_LONG_LONG_INPLACE(operand1, operand2);
1090
1091 // Not every code path will make use of all possible results.
1092#if defined(_MSC_VER)
1093#pragma warning(push)
1094#pragma warning(disable : 4101)
1095#endif
1096 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1097 NUITKA_MAY_BE_UNUSED long clong_result;
1098#if defined(_MSC_VER)
1099#pragma warning(pop)
1100#endif
1101
1102 PyObject *x = PyLong_Type.tp_as_number->nb_divide(*operand1, operand2);
1103 assert(x != Py_NotImplemented);
1104
1105 obj_result = x;
1106 goto exit_result_object;
1107
1108 exit_result_object:
1109 if (unlikely(obj_result == NULL)) {
1110 goto exit_result_exception;
1111 }
1112 // We got an object handed, that we have to release.
1113 Py_DECREF(*operand1);
1114 *operand1 = obj_result;
1115 goto exit_result_ok;
1116
1117 exit_result_ok:
1118 return true;
1119
1120 exit_result_exception:
1121 return false;
1122 }
1123
1124 return __INPLACE_OPERATION_OLDDIV_LONG_OBJECT(operand1, operand2);
1125}
1126
1127bool INPLACE_OPERATION_OLDDIV_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
1128 return _INPLACE_OPERATION_OLDDIV_LONG_OBJECT(operand1, operand2);
1129}
1130#endif
1131
1132#if PYTHON_VERSION < 0x300
1133/* Code referring to "FLOAT" corresponds to Python 'float' and "FLOAT" to Python 'float'. */
1134static inline bool _INPLACE_OPERATION_OLDDIV_FLOAT_FLOAT(PyObject **operand1, PyObject *operand2) {
1135 assert(operand1); // Pointer must be non-null.
1136
1137 CHECK_OBJECT(*operand1);
1138 assert(PyFloat_CheckExact(*operand1));
1139 CHECK_OBJECT(operand2);
1140 assert(PyFloat_CheckExact(operand2));
1141
1142#if defined(_MSC_VER)
1143#pragma warning(push)
1144#pragma warning(disable : 4101)
1145#endif
1146 // Not every code path will make use of all possible results.
1147 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1148 NUITKA_MAY_BE_UNUSED long clong_result;
1149 NUITKA_MAY_BE_UNUSED double cfloat_result;
1150#if defined(_MSC_VER)
1151#pragma warning(pop)
1152#endif
1153
1154 CHECK_OBJECT(*operand1);
1155 assert(PyFloat_CheckExact(*operand1));
1156 CHECK_OBJECT(operand2);
1157 assert(PyFloat_CheckExact(operand2));
1158
1159 const double a = PyFloat_AS_DOUBLE(*operand1);
1160 const double b = PyFloat_AS_DOUBLE(operand2);
1161
1162 if (unlikely(b == 0.0)) {
1163 PyThreadState *tstate = PyThreadState_GET();
1164
1165 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "float division by zero");
1166 goto exit_result_exception;
1167 }
1168
1169 {
1170 double r = a / b;
1171
1172 cfloat_result = r;
1173 goto exit_result_ok_cfloat;
1174 }
1175
1176exit_result_ok_cfloat:
1177 if (Py_REFCNT(*operand1) == 1) {
1178 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1179 } else {
1180 // We got an object handed, that we have to release.
1181 Py_DECREF(*operand1);
1182
1183 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1184 }
1185 goto exit_result_ok;
1186
1187exit_result_ok:
1188 return true;
1189
1190exit_result_exception:
1191 return false;
1192}
1193
1194bool INPLACE_OPERATION_OLDDIV_FLOAT_FLOAT(PyObject **operand1, PyObject *operand2) {
1195 return _INPLACE_OPERATION_OLDDIV_FLOAT_FLOAT(operand1, operand2);
1196}
1197#endif
1198
1199#if PYTHON_VERSION < 0x300
1200/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
1201static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1202 PyTypeObject *type1 = Py_TYPE(*operand1);
1203
1204#if defined(_MSC_VER)
1205#pragma warning(push)
1206#pragma warning(disable : 4101)
1207#endif
1208 NUITKA_MAY_BE_UNUSED bool cbool_result;
1209 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1210#if defined(_MSC_VER)
1211#pragma warning(pop)
1212#endif
1213
1214 binaryfunc islot =
1215 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_divide : NULL;
1216
1217 if (islot != NULL) {
1218 PyObject *x = islot(*operand1, operand2);
1219
1220 if (x != Py_NotImplemented) {
1221 obj_result = x;
1222 goto exit_inplace_result_object;
1223 }
1224
1225 Py_DECREF_IMMORTAL(x);
1226 }
1227
1228 {
1229 binaryfunc slot1 =
1230 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_divide : NULL;
1231 binaryfunc slot2 = NULL;
1232
1233 if (!(type1 == &PyFloat_Type)) {
1234 // Different types, need to consider second value slot.
1235
1236 slot2 = PyFloat_Type.tp_as_number->nb_divide;
1237
1238 if (slot1 == slot2) {
1239 slot2 = NULL;
1240 }
1241 }
1242
1243 if (slot1 != NULL) {
1244 PyObject *x = slot1(*operand1, operand2);
1245
1246 if (x != Py_NotImplemented) {
1247 obj_result = x;
1248 goto exit_inplace_result_object;
1249 }
1250
1251 Py_DECREF_IMMORTAL(x);
1252 }
1253
1254 if (slot2 != NULL) {
1255 PyObject *x = slot2(*operand1, operand2);
1256
1257 if (x != Py_NotImplemented) {
1258 obj_result = x;
1259 goto exit_inplace_result_object;
1260 }
1261
1262 Py_DECREF_IMMORTAL(x);
1263 }
1264
1265#if PYTHON_VERSION < 0x300
1266 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
1267 coercion c1 =
1268 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1269
1270 if (c1 != NULL) {
1271 PyObject *coerced1 = *operand1;
1272 PyObject *coerced2 = operand2;
1273
1274 int err = c1(&coerced1, &coerced2);
1275
1276 if (unlikely(err < 0)) {
1277 goto exit_inplace_exception;
1278 }
1279
1280 if (err == 0) {
1281 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1282
1283 if (likely(mv == NULL)) {
1284 binaryfunc slot = mv->nb_divide;
1285
1286 if (likely(slot != NULL)) {
1287 PyObject *x = slot(coerced1, coerced2);
1288
1289 Py_DECREF(coerced1);
1290 Py_DECREF(coerced2);
1291
1292 obj_result = x;
1293 goto exit_inplace_result_object;
1294 }
1295 }
1296
1297 // nb_coerce took a reference.
1298 Py_DECREF(coerced1);
1299 Py_DECREF(coerced2);
1300 }
1301 }
1302 coercion c2 = PyFloat_Type.tp_as_number->nb_coerce;
1303
1304 if (c2 != NULL) {
1305 PyObject *coerced1 = *operand1;
1306 PyObject *coerced2 = operand2;
1307
1308 int err = c2(&coerced2, &coerced1);
1309
1310 if (unlikely(err < 0)) {
1311 goto exit_inplace_exception;
1312 }
1313
1314 if (err == 0) {
1315 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1316
1317 if (likely(mv == NULL)) {
1318 binaryfunc slot = mv->nb_divide;
1319
1320 if (likely(slot != NULL)) {
1321 PyObject *x = slot(coerced1, coerced2);
1322
1323 Py_DECREF(coerced1);
1324 Py_DECREF(coerced2);
1325
1326 obj_result = x;
1327 goto exit_inplace_result_object;
1328 }
1329 }
1330
1331 // nb_coerce took a reference.
1332 Py_DECREF(coerced1);
1333 Py_DECREF(coerced2);
1334 }
1335 }
1336 }
1337#endif
1338
1339 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: '%s' and 'float'", type1->tp_name);
1340 goto exit_inplace_exception;
1341 }
1342
1343exit_inplace_result_object:
1344 if (unlikely(obj_result == NULL)) {
1345 return false;
1346 }
1347
1348 // We got an object handed, that we have to release.
1349 Py_DECREF(*operand1);
1350
1351 // That's our return value then. As we use a dedicated variable, it's
1352 // OK that way.
1353 *operand1 = obj_result;
1354
1355 return true;
1356
1357exit_inplace_exception:
1358 return false;
1359}
1360static inline bool _INPLACE_OPERATION_OLDDIV_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1361 assert(operand1); // Pointer must be non-null.
1362
1363 CHECK_OBJECT(*operand1);
1364 CHECK_OBJECT(operand2);
1365 assert(PyFloat_CheckExact(operand2));
1366
1367 PyTypeObject *type1 = Py_TYPE(*operand1);
1368
1369 if (type1 == &PyFloat_Type) {
1370 // return _BINARY_OPERATION_OLDDIV_FLOAT_FLOAT_INPLACE(operand1, operand2);
1371
1372#if defined(_MSC_VER)
1373#pragma warning(push)
1374#pragma warning(disable : 4101)
1375#endif
1376 // Not every code path will make use of all possible results.
1377 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1378 NUITKA_MAY_BE_UNUSED long clong_result;
1379 NUITKA_MAY_BE_UNUSED double cfloat_result;
1380#if defined(_MSC_VER)
1381#pragma warning(pop)
1382#endif
1383
1384 CHECK_OBJECT(*operand1);
1385 assert(PyFloat_CheckExact(*operand1));
1386 CHECK_OBJECT(operand2);
1387 assert(PyFloat_CheckExact(operand2));
1388
1389 const double a = PyFloat_AS_DOUBLE(*operand1);
1390 const double b = PyFloat_AS_DOUBLE(operand2);
1391
1392 if (unlikely(b == 0.0)) {
1393 PyThreadState *tstate = PyThreadState_GET();
1394
1395 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "float division by zero");
1396 goto exit_result_exception;
1397 }
1398
1399 {
1400 double r = a / b;
1401
1402 cfloat_result = r;
1403 goto exit_result_ok_cfloat;
1404 }
1405
1406 exit_result_ok_cfloat:
1407 if (Py_REFCNT(*operand1) == 1) {
1408 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1409 } else {
1410 // We got an object handed, that we have to release.
1411 Py_DECREF(*operand1);
1412
1413 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1414 }
1415 goto exit_result_ok;
1416
1417 exit_result_ok:
1418 return true;
1419
1420 exit_result_exception:
1421 return false;
1422 }
1423
1424 return __INPLACE_OPERATION_OLDDIV_OBJECT_FLOAT(operand1, operand2);
1425}
1426
1427bool INPLACE_OPERATION_OLDDIV_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1428 return _INPLACE_OPERATION_OLDDIV_OBJECT_FLOAT(operand1, operand2);
1429}
1430#endif
1431
1432#if PYTHON_VERSION < 0x300
1433/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
1434static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_OLDDIV_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1435 PyTypeObject *type2 = Py_TYPE(operand2);
1436
1437#if defined(_MSC_VER)
1438#pragma warning(push)
1439#pragma warning(disable : 4101)
1440#endif
1441 NUITKA_MAY_BE_UNUSED bool cbool_result;
1442 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1443#if defined(_MSC_VER)
1444#pragma warning(pop)
1445#endif
1446
1447 // No inplace number slot nb_inplace_divide available for this type.
1448
1449 {
1450 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_divide;
1451 binaryfunc slot2 = NULL;
1452
1453 if (!(&PyFloat_Type == type2)) {
1454 // Different types, need to consider second value slot.
1455
1456 slot2 =
1457 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_divide : NULL;
1458
1459 if (slot1 == slot2) {
1460 slot2 = NULL;
1461 }
1462 }
1463
1464 if (slot1 != NULL) {
1465 if (slot2 != NULL) {
1466 if (Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
1467 PyObject *x = slot2(*operand1, operand2);
1468
1469 if (x != Py_NotImplemented) {
1470 obj_result = x;
1471 goto exit_inplace_result_object;
1472 }
1473
1474 Py_DECREF_IMMORTAL(x);
1475 slot2 = NULL;
1476 }
1477 }
1478
1479 PyObject *x = slot1(*operand1, operand2);
1480
1481 if (x != Py_NotImplemented) {
1482 obj_result = x;
1483 goto exit_inplace_result_object;
1484 }
1485
1486 Py_DECREF_IMMORTAL(x);
1487 }
1488
1489 if (slot2 != NULL) {
1490 PyObject *x = slot2(*operand1, operand2);
1491
1492 if (x != Py_NotImplemented) {
1493 obj_result = x;
1494 goto exit_inplace_result_object;
1495 }
1496
1497 Py_DECREF_IMMORTAL(x);
1498 }
1499
1500#if PYTHON_VERSION < 0x300
1501 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1502 coercion c1 = PyFloat_Type.tp_as_number->nb_coerce;
1503
1504 if (c1 != NULL) {
1505 PyObject *coerced1 = *operand1;
1506 PyObject *coerced2 = operand2;
1507
1508 int err = c1(&coerced1, &coerced2);
1509
1510 if (unlikely(err < 0)) {
1511 goto exit_inplace_exception;
1512 }
1513
1514 if (err == 0) {
1515 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1516
1517 if (likely(mv == NULL)) {
1518 binaryfunc slot = mv->nb_divide;
1519
1520 if (likely(slot != NULL)) {
1521 PyObject *x = slot(coerced1, coerced2);
1522
1523 Py_DECREF(coerced1);
1524 Py_DECREF(coerced2);
1525
1526 obj_result = x;
1527 goto exit_inplace_result_object;
1528 }
1529 }
1530
1531 // nb_coerce took a reference.
1532 Py_DECREF(coerced1);
1533 Py_DECREF(coerced2);
1534 }
1535 }
1536 coercion c2 =
1537 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1538
1539 if (c2 != NULL) {
1540 PyObject *coerced1 = *operand1;
1541 PyObject *coerced2 = operand2;
1542
1543 int err = c2(&coerced2, &coerced1);
1544
1545 if (unlikely(err < 0)) {
1546 goto exit_inplace_exception;
1547 }
1548
1549 if (err == 0) {
1550 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1551
1552 if (likely(mv == NULL)) {
1553 binaryfunc slot = mv->nb_divide;
1554
1555 if (likely(slot != NULL)) {
1556 PyObject *x = slot(coerced1, coerced2);
1557
1558 Py_DECREF(coerced1);
1559 Py_DECREF(coerced2);
1560
1561 obj_result = x;
1562 goto exit_inplace_result_object;
1563 }
1564 }
1565
1566 // nb_coerce took a reference.
1567 Py_DECREF(coerced1);
1568 Py_DECREF(coerced2);
1569 }
1570 }
1571 }
1572#endif
1573
1574 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'float' and '%s'", type2->tp_name);
1575 goto exit_inplace_exception;
1576 }
1577
1578exit_inplace_result_object:
1579 if (unlikely(obj_result == NULL)) {
1580 return false;
1581 }
1582
1583 // We got an object handed, that we have to release.
1584 Py_DECREF(*operand1);
1585
1586 // That's our return value then. As we use a dedicated variable, it's
1587 // OK that way.
1588 *operand1 = obj_result;
1589
1590 return true;
1591
1592exit_inplace_exception:
1593 return false;
1594}
1595static inline bool _INPLACE_OPERATION_OLDDIV_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1596 assert(operand1); // Pointer must be non-null.
1597
1598 CHECK_OBJECT(*operand1);
1599 assert(PyFloat_CheckExact(*operand1));
1600 CHECK_OBJECT(operand2);
1601
1602 PyTypeObject *type2 = Py_TYPE(operand2);
1603
1604 if (&PyFloat_Type == type2) {
1605 // return _BINARY_OPERATION_OLDDIV_FLOAT_FLOAT_INPLACE(operand1, operand2);
1606
1607#if defined(_MSC_VER)
1608#pragma warning(push)
1609#pragma warning(disable : 4101)
1610#endif
1611 // Not every code path will make use of all possible results.
1612 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1613 NUITKA_MAY_BE_UNUSED long clong_result;
1614 NUITKA_MAY_BE_UNUSED double cfloat_result;
1615#if defined(_MSC_VER)
1616#pragma warning(pop)
1617#endif
1618
1619 CHECK_OBJECT(*operand1);
1620 assert(PyFloat_CheckExact(*operand1));
1621 CHECK_OBJECT(operand2);
1622 assert(PyFloat_CheckExact(operand2));
1623
1624 const double a = PyFloat_AS_DOUBLE(*operand1);
1625 const double b = PyFloat_AS_DOUBLE(operand2);
1626
1627 if (unlikely(b == 0.0)) {
1628 PyThreadState *tstate = PyThreadState_GET();
1629
1630 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "float division by zero");
1631 goto exit_result_exception;
1632 }
1633
1634 {
1635 double r = a / b;
1636
1637 cfloat_result = r;
1638 goto exit_result_ok_cfloat;
1639 }
1640
1641 exit_result_ok_cfloat:
1642 if (Py_REFCNT(*operand1) == 1) {
1643 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1644 } else {
1645 // We got an object handed, that we have to release.
1646 Py_DECREF(*operand1);
1647
1648 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1649 }
1650 goto exit_result_ok;
1651
1652 exit_result_ok:
1653 return true;
1654
1655 exit_result_exception:
1656 return false;
1657 }
1658
1659 return __INPLACE_OPERATION_OLDDIV_FLOAT_OBJECT(operand1, operand2);
1660}
1661
1662bool INPLACE_OPERATION_OLDDIV_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1663 return _INPLACE_OPERATION_OLDDIV_FLOAT_OBJECT(operand1, operand2);
1664}
1665#endif
1666
1667#if PYTHON_VERSION < 0x300
1668/* Code referring to "FLOAT" corresponds to Python 'float' and "LONG" to Python2 'long', Python3 'int'. */
1669static inline bool _INPLACE_OPERATION_OLDDIV_FLOAT_LONG(PyObject **operand1, PyObject *operand2) {
1670 assert(operand1); // Pointer must be non-null.
1671
1672 CHECK_OBJECT(*operand1);
1673 assert(PyFloat_CheckExact(*operand1));
1674 CHECK_OBJECT(operand2);
1675 assert(PyLong_CheckExact(operand2));
1676
1677#if defined(_MSC_VER)
1678#pragma warning(push)
1679#pragma warning(disable : 4101)
1680#endif
1681 NUITKA_MAY_BE_UNUSED bool cbool_result;
1682 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1683#if defined(_MSC_VER)
1684#pragma warning(pop)
1685#endif
1686
1687 // No inplace number slot nb_inplace_divide available for this type.
1688
1689 {
1690 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_divide;
1691 // Slot2 ignored on purpose, type1 takes precedence.
1692
1693 if (slot1 != NULL) {
1694 PyObject *x = slot1(*operand1, operand2);
1695
1696 if (x != Py_NotImplemented) {
1697 obj_result = x;
1698 goto exit_inplace_result_object;
1699 }
1700
1701 Py_DECREF_IMMORTAL(x);
1702 }
1703
1704 // Statically recognized that coercion is not possible with these types
1705
1706#if PYTHON_VERSION < 0x300
1707 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'float' and 'long'");
1708#else
1709 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'float' and 'int'");
1710#endif
1711 goto exit_inplace_exception;
1712 }
1713
1714exit_inplace_result_object:
1715 if (unlikely(obj_result == NULL)) {
1716 return false;
1717 }
1718
1719 // We got an object handed, that we have to release.
1720 Py_DECREF(*operand1);
1721
1722 // That's our return value then. As we use a dedicated variable, it's
1723 // OK that way.
1724 *operand1 = obj_result;
1725
1726 return true;
1727
1728exit_inplace_exception:
1729 return false;
1730}
1731
1732bool INPLACE_OPERATION_OLDDIV_FLOAT_LONG(PyObject **operand1, PyObject *operand2) {
1733 return _INPLACE_OPERATION_OLDDIV_FLOAT_LONG(operand1, operand2);
1734}
1735#endif
1736
1737#if PYTHON_VERSION < 0x300
1738/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "FLOAT" to Python 'float'. */
1739static inline bool _INPLACE_OPERATION_OLDDIV_LONG_FLOAT(PyObject **operand1, PyObject *operand2) {
1740 assert(operand1); // Pointer must be non-null.
1741
1742 CHECK_OBJECT(*operand1);
1743 assert(PyLong_CheckExact(*operand1));
1744 CHECK_OBJECT(operand2);
1745 assert(PyFloat_CheckExact(operand2));
1746
1747#if defined(_MSC_VER)
1748#pragma warning(push)
1749#pragma warning(disable : 4101)
1750#endif
1751 NUITKA_MAY_BE_UNUSED bool cbool_result;
1752 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1753#if defined(_MSC_VER)
1754#pragma warning(pop)
1755#endif
1756
1757 // No inplace number slot nb_inplace_divide available for this type.
1758
1759 {
1760 // Slot1 ignored on purpose, type2 takes precedence.
1761 binaryfunc slot2 = NULL;
1762
1763 if (!(0)) {
1764 // Different types, need to consider second value slot.
1765
1766 slot2 = PyFloat_Type.tp_as_number->nb_divide;
1767 }
1768
1769 if (slot2 != NULL) {
1770 PyObject *x = slot2(*operand1, operand2);
1771
1772 if (x != Py_NotImplemented) {
1773 obj_result = x;
1774 goto exit_inplace_result_object;
1775 }
1776
1777 Py_DECREF_IMMORTAL(x);
1778 }
1779
1780 // Statically recognized that coercion is not possible with these types
1781
1782#if PYTHON_VERSION < 0x300
1783 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'long' and 'float'");
1784#else
1785 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'int' and 'float'");
1786#endif
1787 goto exit_inplace_exception;
1788 }
1789
1790exit_inplace_result_object:
1791 if (unlikely(obj_result == NULL)) {
1792 return false;
1793 }
1794
1795 // We got an object handed, that we have to release.
1796 Py_DECREF(*operand1);
1797
1798 // That's our return value then. As we use a dedicated variable, it's
1799 // OK that way.
1800 *operand1 = obj_result;
1801
1802 return true;
1803
1804exit_inplace_exception:
1805 return false;
1806}
1807
1808bool INPLACE_OPERATION_OLDDIV_LONG_FLOAT(PyObject **operand1, PyObject *operand2) {
1809 return _INPLACE_OPERATION_OLDDIV_LONG_FLOAT(operand1, operand2);
1810}
1811#endif
1812
1813#if PYTHON_VERSION < 0x300
1814/* Code referring to "FLOAT" corresponds to Python 'float' and "INT" to Python2 'int'. */
1815static inline bool _INPLACE_OPERATION_OLDDIV_FLOAT_INT(PyObject **operand1, PyObject *operand2) {
1816 assert(operand1); // Pointer must be non-null.
1817
1818 CHECK_OBJECT(*operand1);
1819 assert(PyFloat_CheckExact(*operand1));
1820 CHECK_OBJECT(operand2);
1821 assert(PyInt_CheckExact(operand2));
1822
1823#if defined(_MSC_VER)
1824#pragma warning(push)
1825#pragma warning(disable : 4101)
1826#endif
1827 NUITKA_MAY_BE_UNUSED bool cbool_result;
1828 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1829#if defined(_MSC_VER)
1830#pragma warning(pop)
1831#endif
1832
1833 // No inplace number slot nb_inplace_divide available for this type.
1834
1835 {
1836 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_divide;
1837 // Slot2 ignored on purpose, type1 takes precedence.
1838
1839 if (slot1 != NULL) {
1840 PyObject *x = slot1(*operand1, operand2);
1841
1842 if (x != Py_NotImplemented) {
1843 obj_result = x;
1844 goto exit_inplace_result_object;
1845 }
1846
1847 Py_DECREF_IMMORTAL(x);
1848 }
1849
1850 // Statically recognized that coercion is not possible with these types
1851
1852 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'float' and 'int'");
1853 goto exit_inplace_exception;
1854 }
1855
1856exit_inplace_result_object:
1857 if (unlikely(obj_result == NULL)) {
1858 return false;
1859 }
1860
1861 // We got an object handed, that we have to release.
1862 Py_DECREF(*operand1);
1863
1864 // That's our return value then. As we use a dedicated variable, it's
1865 // OK that way.
1866 *operand1 = obj_result;
1867
1868 return true;
1869
1870exit_inplace_exception:
1871 return false;
1872}
1873
1874bool INPLACE_OPERATION_OLDDIV_FLOAT_INT(PyObject **operand1, PyObject *operand2) {
1875 return _INPLACE_OPERATION_OLDDIV_FLOAT_INT(operand1, operand2);
1876}
1877#endif
1878
1879#if PYTHON_VERSION < 0x300
1880/* Code referring to "INT" corresponds to Python2 'int' and "FLOAT" to Python 'float'. */
1881static inline bool _INPLACE_OPERATION_OLDDIV_INT_FLOAT(PyObject **operand1, PyObject *operand2) {
1882 assert(operand1); // Pointer must be non-null.
1883
1884 CHECK_OBJECT(*operand1);
1885 assert(PyInt_CheckExact(*operand1));
1886 CHECK_OBJECT(operand2);
1887 assert(PyFloat_CheckExact(operand2));
1888
1889#if defined(_MSC_VER)
1890#pragma warning(push)
1891#pragma warning(disable : 4101)
1892#endif
1893 NUITKA_MAY_BE_UNUSED bool cbool_result;
1894 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1895#if defined(_MSC_VER)
1896#pragma warning(pop)
1897#endif
1898
1899 // No inplace number slot nb_inplace_divide available for this type.
1900
1901 {
1902 // Slot1 ignored on purpose, type2 takes precedence.
1903 binaryfunc slot2 = NULL;
1904
1905 if (!(0)) {
1906 // Different types, need to consider second value slot.
1907
1908 slot2 = PyFloat_Type.tp_as_number->nb_divide;
1909 }
1910
1911 if (slot2 != NULL) {
1912 PyObject *x = slot2(*operand1, operand2);
1913
1914 if (x != Py_NotImplemented) {
1915 obj_result = x;
1916 goto exit_inplace_result_object;
1917 }
1918
1919 Py_DECREF_IMMORTAL(x);
1920 }
1921
1922 // Statically recognized that coercion is not possible with these types
1923
1924 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'int' and 'float'");
1925 goto exit_inplace_exception;
1926 }
1927
1928exit_inplace_result_object:
1929 if (unlikely(obj_result == NULL)) {
1930 return false;
1931 }
1932
1933 // We got an object handed, that we have to release.
1934 Py_DECREF(*operand1);
1935
1936 // That's our return value then. As we use a dedicated variable, it's
1937 // OK that way.
1938 *operand1 = obj_result;
1939
1940 return true;
1941
1942exit_inplace_exception:
1943 return false;
1944}
1945
1946bool INPLACE_OPERATION_OLDDIV_INT_FLOAT(PyObject **operand1, PyObject *operand2) {
1947 return _INPLACE_OPERATION_OLDDIV_INT_FLOAT(operand1, operand2);
1948}
1949#endif
1950
1951#if PYTHON_VERSION < 0x300
1952/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
1953static inline bool _INPLACE_OPERATION_OLDDIV_LONG_INT(PyObject **operand1, PyObject *operand2) {
1954 assert(operand1); // Pointer must be non-null.
1955
1956 CHECK_OBJECT(*operand1);
1957 assert(PyLong_CheckExact(*operand1));
1958 CHECK_OBJECT(operand2);
1959 assert(PyInt_CheckExact(operand2));
1960
1961#if defined(_MSC_VER)
1962#pragma warning(push)
1963#pragma warning(disable : 4101)
1964#endif
1965 NUITKA_MAY_BE_UNUSED bool cbool_result;
1966 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1967#if defined(_MSC_VER)
1968#pragma warning(pop)
1969#endif
1970
1971 // No inplace number slot nb_inplace_divide available for this type.
1972
1973 {
1974 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_divide;
1975 // Slot2 ignored on purpose, type1 takes precedence.
1976
1977 if (slot1 != NULL) {
1978 PyObject *x = slot1(*operand1, operand2);
1979
1980 if (x != Py_NotImplemented) {
1981 obj_result = x;
1982 goto exit_inplace_result_object;
1983 }
1984
1985 Py_DECREF_IMMORTAL(x);
1986 }
1987
1988 // Statically recognized that coercion is not possible with these types
1989
1990 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'long' and 'int'");
1991 goto exit_inplace_exception;
1992 }
1993
1994exit_inplace_result_object:
1995 if (unlikely(obj_result == NULL)) {
1996 return false;
1997 }
1998
1999 // We got an object handed, that we have to release.
2000 Py_DECREF(*operand1);
2001
2002 // That's our return value then. As we use a dedicated variable, it's
2003 // OK that way.
2004 *operand1 = obj_result;
2005
2006 return true;
2007
2008exit_inplace_exception:
2009 return false;
2010}
2011
2012bool INPLACE_OPERATION_OLDDIV_LONG_INT(PyObject **operand1, PyObject *operand2) {
2013 return _INPLACE_OPERATION_OLDDIV_LONG_INT(operand1, operand2);
2014}
2015#endif
2016
2017#if PYTHON_VERSION < 0x300
2018/* Code referring to "INT" corresponds to Python2 'int' and "LONG" to Python2 'long', Python3 'int'. */
2019static inline bool _INPLACE_OPERATION_OLDDIV_INT_LONG(PyObject **operand1, PyObject *operand2) {
2020 assert(operand1); // Pointer must be non-null.
2021
2022 CHECK_OBJECT(*operand1);
2023 assert(PyInt_CheckExact(*operand1));
2024 CHECK_OBJECT(operand2);
2025 assert(PyLong_CheckExact(operand2));
2026
2027#if defined(_MSC_VER)
2028#pragma warning(push)
2029#pragma warning(disable : 4101)
2030#endif
2031 NUITKA_MAY_BE_UNUSED bool cbool_result;
2032 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2033#if defined(_MSC_VER)
2034#pragma warning(pop)
2035#endif
2036
2037 // No inplace number slot nb_inplace_divide available for this type.
2038
2039 {
2040 // Slot1 ignored on purpose, type2 takes precedence.
2041 binaryfunc slot2 = NULL;
2042
2043 if (!(0)) {
2044 // Different types, need to consider second value slot.
2045
2046 slot2 = PyLong_Type.tp_as_number->nb_divide;
2047 }
2048
2049 if (slot2 != NULL) {
2050 PyObject *x = slot2(*operand1, operand2);
2051
2052 if (x != Py_NotImplemented) {
2053 obj_result = x;
2054 goto exit_inplace_result_object;
2055 }
2056
2057 Py_DECREF_IMMORTAL(x);
2058 }
2059
2060 // Statically recognized that coercion is not possible with these types
2061
2062 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: 'int' and 'long'");
2063 goto exit_inplace_exception;
2064 }
2065
2066exit_inplace_result_object:
2067 if (unlikely(obj_result == NULL)) {
2068 return false;
2069 }
2070
2071 // We got an object handed, that we have to release.
2072 Py_DECREF(*operand1);
2073
2074 // That's our return value then. As we use a dedicated variable, it's
2075 // OK that way.
2076 *operand1 = obj_result;
2077
2078 return true;
2079
2080exit_inplace_exception:
2081 return false;
2082}
2083
2084bool INPLACE_OPERATION_OLDDIV_INT_LONG(PyObject **operand1, PyObject *operand2) {
2085 return _INPLACE_OPERATION_OLDDIV_INT_LONG(operand1, operand2);
2086}
2087#endif
2088
2089#if PYTHON_VERSION < 0x300
2090/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
2091static inline bool _INPLACE_OPERATION_OLDDIV_INT_CLONG(PyObject **operand1, long operand2) {
2092 assert(operand1); // Pointer must be non-null.
2093
2094 CHECK_OBJECT(*operand1);
2095 assert(PyInt_CheckExact(*operand1));
2096
2097 // Not every code path will make use of all possible results.
2098#if defined(_MSC_VER)
2099#pragma warning(push)
2100#pragma warning(disable : 4101)
2101#endif
2102 NUITKA_MAY_BE_UNUSED bool cbool_result;
2103 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2104 NUITKA_MAY_BE_UNUSED long clong_result;
2105 NUITKA_MAY_BE_UNUSED double cfloat_result;
2106#if defined(_MSC_VER)
2107#pragma warning(pop)
2108#endif
2109
2110 CHECK_OBJECT(*operand1);
2111 assert(PyInt_CheckExact(*operand1));
2112
2113 const long a = PyInt_AS_LONG(*operand1);
2114 const long b = operand2;
2115
2116 if (unlikely(b == 0)) {
2117 PyThreadState *tstate = PyThreadState_GET();
2118
2119 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "integer division or modulo by zero");
2120 goto exit_result_exception;
2121 }
2122
2123 /* TODO: Isn't this a very specific value only, of which we could
2124 * hardcode the constant result. Not sure how well the C compiler
2125 * optimizes UNARY_NEG_WOULD_OVERFLOW to this, but dividing by
2126 * -1 has to be rare anyway.
2127 */
2128
2129 if (likely(b != -1 || !UNARY_NEG_WOULD_OVERFLOW(a))) {
2130 long a_div_b = a / b;
2131 long a_mod_b = (long)(a - (unsigned long)a_div_b * b);
2132
2133 if (a_mod_b && (b ^ a_mod_b) < 0) {
2134 a_mod_b += b;
2135 a_div_b -= 1;
2136 }
2137
2138 clong_result = a_div_b;
2139 goto exit_result_ok_clong;
2140 }
2141
2142 {
2143 PyObject *operand1_object = *operand1;
2144 PyObject *operand2_object = Nuitka_PyLong_FromLong(operand2);
2145
2146 PyObject *r = PyLong_Type.tp_as_number->nb_divide(operand1_object, operand2_object);
2147 assert(r != Py_NotImplemented);
2148
2149 Py_DECREF(operand2_object);
2150
2151 obj_result = r;
2152 goto exit_result_object;
2153 }
2154
2155exit_result_ok_clong:
2156
2157 // We got an object handed, that we have to release.
2158 Py_DECREF(*operand1);
2159
2160 // That's our return value then. As we use a dedicated variable, it's
2161 // OK that way.
2162 *operand1 = Nuitka_PyInt_FromLong(clong_result);
2163 goto exit_result_ok;
2164
2165exit_result_object:
2166 if (unlikely(obj_result == NULL)) {
2167 goto exit_result_exception;
2168 }
2169 // We got an object handed, that we have to release.
2170 Py_DECREF(*operand1);
2171
2172 *operand1 = obj_result;
2173 goto exit_result_ok;
2174
2175exit_result_ok:
2176 return true;
2177
2178exit_result_exception:
2179 return false;
2180}
2181
2182bool INPLACE_OPERATION_OLDDIV_INT_CLONG(PyObject **operand1, long operand2) {
2183 return _INPLACE_OPERATION_OLDDIV_INT_CLONG(operand1, operand2);
2184}
2185#endif
2186
2187#if PYTHON_VERSION < 0x300
2188/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
2189static inline bool _INPLACE_OPERATION_OLDDIV_FLOAT_CFLOAT(PyObject **operand1, double operand2) {
2190 assert(operand1); // Pointer must be non-null.
2191
2192 CHECK_OBJECT(*operand1);
2193 assert(PyFloat_CheckExact(*operand1));
2194
2195#if defined(_MSC_VER)
2196#pragma warning(push)
2197#pragma warning(disable : 4101)
2198#endif
2199 // Not every code path will make use of all possible results.
2200 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2201 NUITKA_MAY_BE_UNUSED long clong_result;
2202 NUITKA_MAY_BE_UNUSED double cfloat_result;
2203#if defined(_MSC_VER)
2204#pragma warning(pop)
2205#endif
2206
2207 CHECK_OBJECT(*operand1);
2208 assert(PyFloat_CheckExact(*operand1));
2209
2210 const double a = PyFloat_AS_DOUBLE(*operand1);
2211 const double b = operand2;
2212
2213 if (unlikely(b == 0.0)) {
2214 PyThreadState *tstate = PyThreadState_GET();
2215
2216 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "float division by zero");
2217 goto exit_result_exception;
2218 }
2219
2220 {
2221 double r = a / b;
2222
2223 cfloat_result = r;
2224 goto exit_result_ok_cfloat;
2225 }
2226
2227exit_result_ok_cfloat:
2228 if (Py_REFCNT(*operand1) == 1) {
2229 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
2230 } else {
2231 // We got an object handed, that we have to release.
2232 Py_DECREF(*operand1);
2233
2234 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
2235 }
2236 goto exit_result_ok;
2237
2238exit_result_ok:
2239 return true;
2240
2241exit_result_exception:
2242 return false;
2243}
2244
2245bool INPLACE_OPERATION_OLDDIV_FLOAT_CFLOAT(PyObject **operand1, double operand2) {
2246 return _INPLACE_OPERATION_OLDDIV_FLOAT_CFLOAT(operand1, operand2);
2247}
2248#endif
2249
2250#if PYTHON_VERSION < 0x300
2251/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
2252static inline bool _INPLACE_OPERATION_OLDDIV_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
2253 assert(operand1); // Pointer must be non-null.
2254
2255 CHECK_OBJECT(*operand1);
2256 CHECK_OBJECT(operand2);
2257
2258#if PYTHON_VERSION < 0x300
2259 if (PyInt_CheckExact(*operand1) && PyInt_CheckExact(operand2)) {
2260
2261 // Not every code path will make use of all possible results.
2262#if defined(_MSC_VER)
2263#pragma warning(push)
2264#pragma warning(disable : 4101)
2265#endif
2266 NUITKA_MAY_BE_UNUSED bool cbool_result;
2267 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2268 NUITKA_MAY_BE_UNUSED long clong_result;
2269 NUITKA_MAY_BE_UNUSED double cfloat_result;
2270#if defined(_MSC_VER)
2271#pragma warning(pop)
2272#endif
2273
2274 CHECK_OBJECT(*operand1);
2275 assert(PyInt_CheckExact(*operand1));
2276 CHECK_OBJECT(operand2);
2277 assert(PyInt_CheckExact(operand2));
2278
2279 const long a = PyInt_AS_LONG(*operand1);
2280 const long b = PyInt_AS_LONG(operand2);
2281
2282 if (unlikely(b == 0)) {
2283 PyThreadState *tstate = PyThreadState_GET();
2284
2285 SET_CURRENT_EXCEPTION_TYPE0_STR(tstate, PyExc_ZeroDivisionError, "integer division or modulo by zero");
2286 goto exit_result_exception;
2287 }
2288
2289 /* TODO: Isn't this a very specific value only, of which we could
2290 * hardcode the constant result. Not sure how well the C compiler
2291 * optimizes UNARY_NEG_WOULD_OVERFLOW to this, but dividing by
2292 * -1 has to be rare anyway.
2293 */
2294
2295 if (likely(b != -1 || !UNARY_NEG_WOULD_OVERFLOW(a))) {
2296 long a_div_b = a / b;
2297 long a_mod_b = (long)(a - (unsigned long)a_div_b * b);
2298
2299 if (a_mod_b && (b ^ a_mod_b) < 0) {
2300 a_mod_b += b;
2301 a_div_b -= 1;
2302 }
2303
2304 clong_result = a_div_b;
2305 goto exit_result_ok_clong;
2306 }
2307
2308 {
2309 PyObject *operand1_object = *operand1;
2310 PyObject *operand2_object = operand2;
2311
2312 PyObject *r = PyLong_Type.tp_as_number->nb_divide(operand1_object, operand2_object);
2313 assert(r != Py_NotImplemented);
2314
2315 obj_result = r;
2316 goto exit_result_object;
2317 }
2318
2319 exit_result_ok_clong:
2320
2321 // We got an object handed, that we have to release.
2322 Py_DECREF(*operand1);
2323
2324 // That's our return value then. As we use a dedicated variable, it's
2325 // OK that way.
2326 *operand1 = Nuitka_PyInt_FromLong(clong_result);
2327 goto exit_result_ok;
2328
2329 exit_result_object:
2330 if (unlikely(obj_result == NULL)) {
2331 goto exit_result_exception;
2332 }
2333 // We got an object handed, that we have to release.
2334 Py_DECREF(*operand1);
2335
2336 *operand1 = obj_result;
2337 goto exit_result_ok;
2338
2339 exit_result_ok:
2340 return true;
2341
2342 exit_result_exception:
2343 return false;
2344 }
2345#endif
2346
2347 if (Py_TYPE(*operand1) == Py_TYPE(operand2)) {
2348 if (PyFloat_CheckExact(operand2)) {
2349 return _INPLACE_OPERATION_OLDDIV_FLOAT_FLOAT(operand1, operand2);
2350 }
2351#if PYTHON_VERSION >= 0x300
2352 if (PyLong_CheckExact(operand2)) {
2353 return _INPLACE_OPERATION_OLDDIV_LONG_LONG(operand1, operand2);
2354 }
2355#endif
2356 }
2357
2358 PyTypeObject *type1 = Py_TYPE(*operand1);
2359 PyTypeObject *type2 = Py_TYPE(operand2);
2360
2361#if defined(_MSC_VER)
2362#pragma warning(push)
2363#pragma warning(disable : 4101)
2364#endif
2365 NUITKA_MAY_BE_UNUSED bool cbool_result;
2366 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2367#if defined(_MSC_VER)
2368#pragma warning(pop)
2369#endif
2370
2371 binaryfunc islot =
2372 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_divide : NULL;
2373
2374 if (islot != NULL) {
2375 PyObject *x = islot(*operand1, operand2);
2376
2377 if (x != Py_NotImplemented) {
2378 obj_result = x;
2379 goto exit_inplace_result_object;
2380 }
2381
2382 Py_DECREF_IMMORTAL(x);
2383 }
2384
2385 {
2386 binaryfunc slot1 =
2387 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_divide : NULL;
2388 binaryfunc slot2 = NULL;
2389
2390 if (!(type1 == type2)) {
2391 // Different types, need to consider second value slot.
2392
2393 slot2 =
2394 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_divide : NULL;
2395
2396 if (slot1 == slot2) {
2397 slot2 = NULL;
2398 }
2399 }
2400
2401 if (slot1 != NULL) {
2402 if (slot2 != NULL) {
2403 if (Nuitka_Type_IsSubtype(type2, type1)) {
2404 PyObject *x = slot2(*operand1, operand2);
2405
2406 if (x != Py_NotImplemented) {
2407 obj_result = x;
2408 goto exit_inplace_result_object;
2409 }
2410
2411 Py_DECREF_IMMORTAL(x);
2412 slot2 = NULL;
2413 }
2414 }
2415
2416 PyObject *x = slot1(*operand1, operand2);
2417
2418 if (x != Py_NotImplemented) {
2419 obj_result = x;
2420 goto exit_inplace_result_object;
2421 }
2422
2423 Py_DECREF_IMMORTAL(x);
2424 }
2425
2426 if (slot2 != NULL) {
2427 PyObject *x = slot2(*operand1, operand2);
2428
2429 if (x != Py_NotImplemented) {
2430 obj_result = x;
2431 goto exit_inplace_result_object;
2432 }
2433
2434 Py_DECREF_IMMORTAL(x);
2435 }
2436
2437#if PYTHON_VERSION < 0x300
2438 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
2439 coercion c1 =
2440 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
2441
2442 if (c1 != NULL) {
2443 PyObject *coerced1 = *operand1;
2444 PyObject *coerced2 = operand2;
2445
2446 int err = c1(&coerced1, &coerced2);
2447
2448 if (unlikely(err < 0)) {
2449 goto exit_inplace_exception;
2450 }
2451
2452 if (err == 0) {
2453 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2454
2455 if (likely(mv == NULL)) {
2456 binaryfunc slot = mv->nb_divide;
2457
2458 if (likely(slot != NULL)) {
2459 PyObject *x = slot(coerced1, coerced2);
2460
2461 Py_DECREF(coerced1);
2462 Py_DECREF(coerced2);
2463
2464 obj_result = x;
2465 goto exit_inplace_result_object;
2466 }
2467 }
2468
2469 // nb_coerce took a reference.
2470 Py_DECREF(coerced1);
2471 Py_DECREF(coerced2);
2472 }
2473 }
2474 coercion c2 =
2475 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
2476
2477 if (c2 != NULL) {
2478 PyObject *coerced1 = *operand1;
2479 PyObject *coerced2 = operand2;
2480
2481 int err = c2(&coerced2, &coerced1);
2482
2483 if (unlikely(err < 0)) {
2484 goto exit_inplace_exception;
2485 }
2486
2487 if (err == 0) {
2488 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
2489
2490 if (likely(mv == NULL)) {
2491 binaryfunc slot = mv->nb_divide;
2492
2493 if (likely(slot != NULL)) {
2494 PyObject *x = slot(coerced1, coerced2);
2495
2496 Py_DECREF(coerced1);
2497 Py_DECREF(coerced2);
2498
2499 obj_result = x;
2500 goto exit_inplace_result_object;
2501 }
2502 }
2503
2504 // nb_coerce took a reference.
2505 Py_DECREF(coerced1);
2506 Py_DECREF(coerced2);
2507 }
2508 }
2509 }
2510#endif
2511
2512 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for /=: '%s' and '%s'", type1->tp_name,
2513 type2->tp_name);
2514 goto exit_inplace_exception;
2515 }
2516
2517exit_inplace_result_object:
2518 if (unlikely(obj_result == NULL)) {
2519 return false;
2520 }
2521
2522 // We got an object handed, that we have to release.
2523 Py_DECREF(*operand1);
2524
2525 // That's our return value then. As we use a dedicated variable, it's
2526 // OK that way.
2527 *operand1 = obj_result;
2528
2529 return true;
2530
2531exit_inplace_exception:
2532 return false;
2533}
2534
2535bool INPLACE_OPERATION_OLDDIV_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
2536 return _INPLACE_OPERATION_OLDDIV_OBJECT_OBJECT(operand1, operand2);
2537}
2538#endif
2539
2540// Part of "Nuitka", an optimizing Python compiler that is compatible and
2541// integrates with CPython, but also works on its own.
2542//
2543// Licensed under the Apache License, Version 2.0 (the "License");
2544// you may not use this file except in compliance with the License.
2545// You may obtain a copy of the License at
2546//
2547// http://www.apache.org/licenses/LICENSE-2.0
2548//
2549// Unless required by applicable law or agreed to in writing, software
2550// distributed under the License is distributed on an "AS IS" BASIS,
2551// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
2552// See the License for the specific language governing permissions and
2553// limitations under the License.