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