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