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