Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersComparisonGt.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 HelperOperationComparison.c.j2 instead! */
4
5/* This file is included from another C file, help IDEs to still parse it on its own. */
6#ifdef __IDE_ONLY__
7#include "nuitka/prelude.h"
8#endif
9
10/* C helpers for type specialized ">" (GT) comparisons */
11
12#if PYTHON_VERSION < 0x300
13static PyObject *COMPARE_GT_OBJECT_INT_INT(PyObject *operand1, PyObject *operand2) {
14 CHECK_OBJECT(operand1);
15 assert(PyInt_CheckExact(operand1));
16 CHECK_OBJECT(operand2);
17 assert(PyInt_CheckExact(operand2));
18
19 const long a = PyInt_AS_LONG(operand1);
20 const long b = PyInt_AS_LONG(operand2);
21
22 bool r = a > b;
23
24 // Convert to target type.
25 PyObject *result = BOOL_FROM(r);
26 Py_INCREF_IMMORTAL(result);
27 return result;
28}
29#endif
30#if PYTHON_VERSION < 0x300
31static bool COMPARE_GT_CBOOL_INT_INT(PyObject *operand1, PyObject *operand2) {
32 CHECK_OBJECT(operand1);
33 assert(PyInt_CheckExact(operand1));
34 CHECK_OBJECT(operand2);
35 assert(PyInt_CheckExact(operand2));
36
37 const long a = PyInt_AS_LONG(operand1);
38 const long b = PyInt_AS_LONG(operand2);
39
40 bool r = a > b;
41
42 // Convert to target type.
43 bool result = r;
44
45 return result;
46}
47#endif
48/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
49PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
50
51#if PYTHON_VERSION < 0x300
52 if (PyInt_CheckExact(operand1) && PyInt_CheckExact(operand2)) {
53 return COMPARE_GT_OBJECT_INT_INT(operand1, operand2);
54 }
55#endif
56
57#if PYTHON_VERSION < 0x300
58 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
59 return NULL;
60 }
61#else
62 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
63 return NULL;
64 }
65#endif
66
67 PyTypeObject *type1 = Py_TYPE(operand1);
68 PyTypeObject *type2 = Py_TYPE(operand2);
69
70#if PYTHON_VERSION < 0x300
71 // If the types are equal, we may get away immediately except for instances.
72 if (type1 == type2 && !PyInstance_Check(operand1)) {
73
74 richcmpfunc frich = TP_RICHCOMPARE(type1);
75
76 if (frich != NULL) {
77 PyObject *result = (*frich)(operand1, operand2, Py_GT);
78
79 if (result != Py_NotImplemented) {
80 Py_LeaveRecursiveCall();
81
82 return result;
83 }
84
85 Py_DECREF_IMMORTAL(result);
86 }
87
88 // No rich comparison worked, but maybe compare works.
89 cmpfunc fcmp = type1->tp_compare;
90
91 if (fcmp != NULL) {
92 int c = (*fcmp)(operand1, operand2);
93 c = adjust_tp_compare(c);
94
95 Py_LeaveRecursiveCall();
96
97 if (c == -2) {
98 return NULL;
99 }
100
101 switch (Py_GT) {
102 case Py_LT:
103 c = c < 0;
104 break;
105 case Py_LE:
106 c = c <= 0;
107 break;
108 case Py_EQ:
109 c = c == 0;
110 break;
111 case Py_NE:
112 c = c != 0;
113 break;
114 case Py_GT:
115 c = c > 0;
116 break;
117 case Py_GE:
118 c = c >= 0;
119 break;
120 default:
121 NUITKA_CANNOT_GET_HERE("wrong op_code");
122 }
123
124 bool r = c != 0;
125 PyObject *result = BOOL_FROM(r);
126 Py_INCREF_IMMORTAL(result);
127 return result;
128 }
129 }
130
131 // Fast path was not successful or not taken
132 richcmpfunc f;
133
134 if (type1 != type2 && Nuitka_Type_IsSubtype(type2, type1)) {
135 f = TP_RICHCOMPARE(type2);
136
137 if (f != NULL) {
138 PyObject *result = (*f)(operand2, operand1, Py_LT);
139
140 if (result != Py_NotImplemented) {
141 Py_LeaveRecursiveCall();
142
143 return result;
144 }
145
146 Py_DECREF_IMMORTAL(result);
147 }
148 }
149
150 f = TP_RICHCOMPARE(type1);
151 if (f != NULL) {
152 PyObject *result = (*f)(operand1, operand2, Py_GT);
153
154 if (result != Py_NotImplemented) {
155 Py_LeaveRecursiveCall();
156
157 return result;
158 }
159
160 Py_DECREF_IMMORTAL(result);
161 }
162
163 f = TP_RICHCOMPARE(type2);
164 if (f != NULL) {
165 PyObject *result = (*f)(operand2, operand1, Py_LT);
166
167 if (result != Py_NotImplemented) {
168 Py_LeaveRecursiveCall();
169
170 return result;
171 }
172
173 Py_DECREF_IMMORTAL(result);
174 }
175
176 int c;
177
178 if (PyInstance_Check(operand1)) {
179 cmpfunc fcmp = type1->tp_compare;
180 c = (*fcmp)(operand1, operand2);
181 } else if (PyInstance_Check(operand2)) {
182 cmpfunc fcmp = type2->tp_compare;
183 c = (*fcmp)(operand1, operand2);
184 } else {
185 c = try_3way_compare(operand1, operand2);
186 }
187
188 if (c >= 2) {
189 if (type1 == type2) {
190 Py_uintptr_t aa = (Py_uintptr_t)operand1;
191 Py_uintptr_t bb = (Py_uintptr_t)operand2;
192
193 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
194 } else if (operand1 == Py_None) {
195 // None is smaller than everything else
196 c = -1;
197 } else if (operand2 == Py_None) {
198 // None is smaller than everything else
199 c = 1;
200 } else if (PyNumber_Check(operand1)) {
201 // different type: compare type names but numbers are smaller than
202 // others.
203 if (PyNumber_Check(operand2)) {
204 // Both numbers, need to make a decision based on types.
205 Py_uintptr_t aa = (Py_uintptr_t)type1;
206 Py_uintptr_t bb = (Py_uintptr_t)type2;
207
208 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
209 } else {
210 c = -1;
211 }
212 } else if (PyNumber_Check(operand2)) {
213 c = 1;
214 } else {
215 // Banking on C compile to optimize "strcmp".
216 int s = strcmp(type1->tp_name, type2->tp_name);
217
218 if (s < 0) {
219 c = -1;
220 } else if (s > 0) {
221 c = 1;
222 } else {
223 // Same type name need to make a decision based on type address.
224 Py_uintptr_t aa = (Py_uintptr_t)type1;
225 Py_uintptr_t bb = (Py_uintptr_t)type2;
226
227 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
228 }
229 }
230 }
231
232 Py_LeaveRecursiveCall();
233
234 if (unlikely(c <= -2)) {
235 return NULL;
236 }
237
238 switch (Py_GT) {
239 case Py_LT:
240 c = c < 0;
241 break;
242 case Py_LE:
243 c = c <= 0;
244 break;
245 case Py_EQ:
246 c = c == 0;
247 break;
248 case Py_NE:
249 c = c != 0;
250 break;
251 case Py_GT:
252 c = c > 0;
253 break;
254 case Py_GE:
255 c = c >= 0;
256 break;
257 }
258
259 bool r = c != 0;
260 PyObject *result = BOOL_FROM(r);
261 Py_INCREF_IMMORTAL(result);
262 return result;
263#else
264 bool checked_reverse_op = false;
265 richcmpfunc f;
266
267 if (type1 != type2 && Nuitka_Type_IsSubtype(type2, type1)) {
268 f = TP_RICHCOMPARE(type2);
269
270 if (f != NULL) {
271 checked_reverse_op = true;
272
273 PyObject *result = (*f)(operand2, operand1, Py_LT);
274
275 if (result != Py_NotImplemented) {
276 Py_LeaveRecursiveCall();
277
278 return result;
279 }
280
281 Py_DECREF_IMMORTAL(result);
282 }
283 }
284
285 f = TP_RICHCOMPARE(type1);
286
287 if (f != NULL) {
288 PyObject *result = (*f)(operand1, operand2, Py_GT);
289
290 if (result != Py_NotImplemented) {
291 Py_LeaveRecursiveCall();
292
293 return result;
294 }
295
296 Py_DECREF_IMMORTAL(result);
297 }
298
299 if (checked_reverse_op == false) {
300 f = TP_RICHCOMPARE(type2);
301
302 if (f != NULL) {
303 PyObject *result = (*f)(operand2, operand1, Py_LT);
304
305 if (result != Py_NotImplemented) {
306 Py_LeaveRecursiveCall();
307
308 return result;
309 }
310
311 Py_DECREF_IMMORTAL(result);
312 }
313 }
314
315 Py_LeaveRecursiveCall();
316
317 // If it is not implemented, do pointer identity checks as "==" and "!=" and
318 // otherwise give an error
319 switch (Py_GT) {
320 case Py_EQ: {
321 bool r = operand1 == operand2;
322 PyObject *result = BOOL_FROM(r);
323 Py_INCREF_IMMORTAL(result);
324 return result;
325 }
326 case Py_NE: {
327 bool r = operand1 != operand2;
328 PyObject *result = BOOL_FROM(r);
329 Py_INCREF_IMMORTAL(result);
330 return result;
331 }
332 default:
333#if PYTHON_VERSION < 0x360
334 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > %s()", type1->tp_name, type2->tp_name);
335#else
336 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and '%s'", type1->tp_name,
337 type2->tp_name);
338#endif
339 return NULL;
340 }
341#endif
342}
343
344/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
345nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_OBJECT(PyObject *operand1, PyObject *operand2) {
346
347#if PYTHON_VERSION < 0x300
348 if (PyInt_CheckExact(operand1) && PyInt_CheckExact(operand2)) {
349 return COMPARE_GT_CBOOL_INT_INT(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
350 }
351#endif
352
353#if PYTHON_VERSION < 0x300
354 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
355 return NUITKA_BOOL_EXCEPTION;
356 }
357#else
358 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
359 return NUITKA_BOOL_EXCEPTION;
360 }
361#endif
362
363 PyTypeObject *type1 = Py_TYPE(operand1);
364 PyTypeObject *type2 = Py_TYPE(operand2);
365
366#if PYTHON_VERSION < 0x300
367 // If the types are equal, we may get away immediately except for instances.
368 if (type1 == type2 && !PyInstance_Check(operand1)) {
369
370 richcmpfunc frich = TP_RICHCOMPARE(type1);
371
372 if (frich != NULL) {
373 PyObject *result = (*frich)(operand1, operand2, Py_GT);
374
375 if (result != Py_NotImplemented) {
376 Py_LeaveRecursiveCall();
377
378 if (unlikely(result == NULL)) {
379 return NUITKA_BOOL_EXCEPTION;
380 }
381
382 {
383 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
384 Py_DECREF(result);
385 return r;
386 }
387 }
388
389 Py_DECREF_IMMORTAL(result);
390 }
391
392 // No rich comparison worked, but maybe compare works.
393 cmpfunc fcmp = type1->tp_compare;
394
395 if (fcmp != NULL) {
396 int c = (*fcmp)(operand1, operand2);
397 c = adjust_tp_compare(c);
398
399 Py_LeaveRecursiveCall();
400
401 if (c == -2) {
402 return NUITKA_BOOL_EXCEPTION;
403 }
404
405 switch (Py_GT) {
406 case Py_LT:
407 c = c < 0;
408 break;
409 case Py_LE:
410 c = c <= 0;
411 break;
412 case Py_EQ:
413 c = c == 0;
414 break;
415 case Py_NE:
416 c = c != 0;
417 break;
418 case Py_GT:
419 c = c > 0;
420 break;
421 case Py_GE:
422 c = c >= 0;
423 break;
424 default:
425 NUITKA_CANNOT_GET_HERE("wrong op_code");
426 }
427
428 bool r = c != 0;
429 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
430
431 return result;
432 }
433 }
434
435 // Fast path was not successful or not taken
436 richcmpfunc f;
437
438 if (type1 != type2 && Nuitka_Type_IsSubtype(type2, type1)) {
439 f = TP_RICHCOMPARE(type2);
440
441 if (f != NULL) {
442 PyObject *result = (*f)(operand2, operand1, Py_LT);
443
444 if (result != Py_NotImplemented) {
445 Py_LeaveRecursiveCall();
446
447 if (unlikely(result == NULL)) {
448 return NUITKA_BOOL_EXCEPTION;
449 }
450
451 {
452 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
453 Py_DECREF(result);
454 return r;
455 }
456 }
457
458 Py_DECREF_IMMORTAL(result);
459 }
460 }
461
462 f = TP_RICHCOMPARE(type1);
463 if (f != NULL) {
464 PyObject *result = (*f)(operand1, operand2, Py_GT);
465
466 if (result != Py_NotImplemented) {
467 Py_LeaveRecursiveCall();
468
469 if (unlikely(result == NULL)) {
470 return NUITKA_BOOL_EXCEPTION;
471 }
472
473 {
474 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
475 Py_DECREF(result);
476 return r;
477 }
478 }
479
480 Py_DECREF_IMMORTAL(result);
481 }
482
483 f = TP_RICHCOMPARE(type2);
484 if (f != NULL) {
485 PyObject *result = (*f)(operand2, operand1, Py_LT);
486
487 if (result != Py_NotImplemented) {
488 Py_LeaveRecursiveCall();
489
490 if (unlikely(result == NULL)) {
491 return NUITKA_BOOL_EXCEPTION;
492 }
493
494 {
495 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
496 Py_DECREF(result);
497 return r;
498 }
499 }
500
501 Py_DECREF_IMMORTAL(result);
502 }
503
504 int c;
505
506 if (PyInstance_Check(operand1)) {
507 cmpfunc fcmp = type1->tp_compare;
508 c = (*fcmp)(operand1, operand2);
509 } else if (PyInstance_Check(operand2)) {
510 cmpfunc fcmp = type2->tp_compare;
511 c = (*fcmp)(operand1, operand2);
512 } else {
513 c = try_3way_compare(operand1, operand2);
514 }
515
516 if (c >= 2) {
517 if (type1 == type2) {
518 Py_uintptr_t aa = (Py_uintptr_t)operand1;
519 Py_uintptr_t bb = (Py_uintptr_t)operand2;
520
521 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
522 } else if (operand1 == Py_None) {
523 // None is smaller than everything else
524 c = -1;
525 } else if (operand2 == Py_None) {
526 // None is smaller than everything else
527 c = 1;
528 } else if (PyNumber_Check(operand1)) {
529 // different type: compare type names but numbers are smaller than
530 // others.
531 if (PyNumber_Check(operand2)) {
532 // Both numbers, need to make a decision based on types.
533 Py_uintptr_t aa = (Py_uintptr_t)type1;
534 Py_uintptr_t bb = (Py_uintptr_t)type2;
535
536 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
537 } else {
538 c = -1;
539 }
540 } else if (PyNumber_Check(operand2)) {
541 c = 1;
542 } else {
543 // Banking on C compile to optimize "strcmp".
544 int s = strcmp(type1->tp_name, type2->tp_name);
545
546 if (s < 0) {
547 c = -1;
548 } else if (s > 0) {
549 c = 1;
550 } else {
551 // Same type name need to make a decision based on type address.
552 Py_uintptr_t aa = (Py_uintptr_t)type1;
553 Py_uintptr_t bb = (Py_uintptr_t)type2;
554
555 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
556 }
557 }
558 }
559
560 Py_LeaveRecursiveCall();
561
562 if (unlikely(c <= -2)) {
563 return NUITKA_BOOL_EXCEPTION;
564 }
565
566 switch (Py_GT) {
567 case Py_LT:
568 c = c < 0;
569 break;
570 case Py_LE:
571 c = c <= 0;
572 break;
573 case Py_EQ:
574 c = c == 0;
575 break;
576 case Py_NE:
577 c = c != 0;
578 break;
579 case Py_GT:
580 c = c > 0;
581 break;
582 case Py_GE:
583 c = c >= 0;
584 break;
585 }
586
587 bool r = c != 0;
588 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
589
590 return result;
591#else
592 bool checked_reverse_op = false;
593 richcmpfunc f;
594
595 if (type1 != type2 && Nuitka_Type_IsSubtype(type2, type1)) {
596 f = TP_RICHCOMPARE(type2);
597
598 if (f != NULL) {
599 checked_reverse_op = true;
600
601 PyObject *result = (*f)(operand2, operand1, Py_LT);
602
603 if (result != Py_NotImplemented) {
604 Py_LeaveRecursiveCall();
605
606 if (unlikely(result == NULL)) {
607 return NUITKA_BOOL_EXCEPTION;
608 }
609
610 {
611 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
612 Py_DECREF(result);
613 return r;
614 }
615 }
616
617 Py_DECREF_IMMORTAL(result);
618 }
619 }
620
621 f = TP_RICHCOMPARE(type1);
622
623 if (f != NULL) {
624 PyObject *result = (*f)(operand1, operand2, Py_GT);
625
626 if (result != Py_NotImplemented) {
627 Py_LeaveRecursiveCall();
628
629 if (unlikely(result == NULL)) {
630 return NUITKA_BOOL_EXCEPTION;
631 }
632
633 {
634 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
635 Py_DECREF(result);
636 return r;
637 }
638 }
639
640 Py_DECREF_IMMORTAL(result);
641 }
642
643 if (checked_reverse_op == false) {
644 f = TP_RICHCOMPARE(type2);
645
646 if (f != NULL) {
647 PyObject *result = (*f)(operand2, operand1, Py_LT);
648
649 if (result != Py_NotImplemented) {
650 Py_LeaveRecursiveCall();
651
652 if (unlikely(result == NULL)) {
653 return NUITKA_BOOL_EXCEPTION;
654 }
655
656 {
657 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
658 Py_DECREF(result);
659 return r;
660 }
661 }
662
663 Py_DECREF_IMMORTAL(result);
664 }
665 }
666
667 Py_LeaveRecursiveCall();
668
669 // If it is not implemented, do pointer identity checks as "==" and "!=" and
670 // otherwise give an error
671 switch (Py_GT) {
672 case Py_EQ: {
673 bool r = operand1 == operand2;
674 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
675
676 return result;
677 }
678 case Py_NE: {
679 bool r = operand1 != operand2;
680 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
681
682 return result;
683 }
684 default:
685#if PYTHON_VERSION < 0x360
686 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > %s()", type1->tp_name, type2->tp_name);
687#else
688 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and '%s'", type1->tp_name,
689 type2->tp_name);
690#endif
691 return NUITKA_BOOL_EXCEPTION;
692 }
693#endif
694}
695
696#if PYTHON_VERSION < 0x300
697static PyObject *COMPARE_GT_OBJECT_STR_STR(PyObject *operand1, PyObject *operand2) {
698 CHECK_OBJECT(operand1);
699 assert(PyString_CheckExact(operand1));
700 CHECK_OBJECT(operand2);
701 assert(PyString_CheckExact(operand2));
702
703 PyStringObject *a = (PyStringObject *)operand1;
704 PyStringObject *b = (PyStringObject *)operand2;
705
706 // Same object has fast path for all operations.
707 if (operand1 == operand2) {
708 bool r = false;
709
710 // Convert to target type.
711 PyObject *result = BOOL_FROM(r);
712 Py_INCREF_IMMORTAL(result);
713 return result;
714 }
715
716 Py_ssize_t len_a = Py_SIZE(operand1);
717 Py_ssize_t len_b = Py_SIZE(operand2);
718
719 Py_ssize_t min_len = (len_a < len_b) ? len_a : len_b;
720 int c;
721
722 if (min_len > 0) {
723 c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
724
725 if (c == 0) {
726 c = memcmp(a->ob_sval, b->ob_sval, min_len);
727 }
728 } else {
729 c = 0;
730 }
731
732 if (c == 0) {
733 c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
734 }
735
736 c = c > 0;
737
738 // Convert to target type.
739 PyObject *result = BOOL_FROM(c != 0);
740 Py_INCREF_IMMORTAL(result);
741 return result;
742}
743#endif
744#if PYTHON_VERSION < 0x300
745/* Code referring to "OBJECT" corresponds to any Python object and "STR" to Python2 'str'. */
746PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_STR(PyObject *operand1, PyObject *operand2) {
747
748 if (Py_TYPE(operand1) == &PyString_Type) {
749 return COMPARE_GT_OBJECT_STR_STR(operand1, operand2);
750 }
751
752#if PYTHON_VERSION < 0x300
753 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
754 return NULL;
755 }
756#else
757 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
758 return NULL;
759 }
760#endif
761
762 PyTypeObject *type1 = Py_TYPE(operand1);
763
764#if PYTHON_VERSION < 0x300
765 // If the types are equal, we may get away immediately except for instances.
766 if (type1 == &PyString_Type && !0) {
767
768 richcmpfunc frich = PyString_Type.tp_richcompare;
769
770 if (frich != NULL) {
771 PyObject *result = (*frich)(operand1, operand2, Py_GT);
772
773 if (result != Py_NotImplemented) {
774 Py_LeaveRecursiveCall();
775
776 return result;
777 }
778
779 Py_DECREF_IMMORTAL(result);
780 }
781
782 // No rich comparison worked, but maybe compare works.
783 cmpfunc fcmp = NULL;
784
785 if (fcmp != NULL) {
786 int c = (*fcmp)(operand1, operand2);
787 c = adjust_tp_compare(c);
788
789 Py_LeaveRecursiveCall();
790
791 if (c == -2) {
792 return NULL;
793 }
794
795 switch (Py_GT) {
796 case Py_LT:
797 c = c < 0;
798 break;
799 case Py_LE:
800 c = c <= 0;
801 break;
802 case Py_EQ:
803 c = c == 0;
804 break;
805 case Py_NE:
806 c = c != 0;
807 break;
808 case Py_GT:
809 c = c > 0;
810 break;
811 case Py_GE:
812 c = c >= 0;
813 break;
814 default:
815 NUITKA_CANNOT_GET_HERE("wrong op_code");
816 }
817
818 bool r = c != 0;
819 PyObject *result = BOOL_FROM(r);
820 Py_INCREF_IMMORTAL(result);
821 return result;
822 }
823 }
824
825 // Fast path was not successful or not taken
826 richcmpfunc f;
827
828 if (type1 != &PyString_Type && 0) {
829 f = PyString_Type.tp_richcompare;
830
831 if (f != NULL) {
832 PyObject *result = (*f)(operand2, operand1, Py_LT);
833
834 if (result != Py_NotImplemented) {
835 Py_LeaveRecursiveCall();
836
837 return result;
838 }
839
840 Py_DECREF_IMMORTAL(result);
841 }
842 }
843
844 f = TP_RICHCOMPARE(type1);
845 if (f != NULL) {
846 PyObject *result = (*f)(operand1, operand2, Py_GT);
847
848 if (result != Py_NotImplemented) {
849 Py_LeaveRecursiveCall();
850
851 return result;
852 }
853
854 Py_DECREF_IMMORTAL(result);
855 }
856
857 f = PyString_Type.tp_richcompare;
858 if (f != NULL) {
859 PyObject *result = (*f)(operand2, operand1, Py_LT);
860
861 if (result != Py_NotImplemented) {
862 Py_LeaveRecursiveCall();
863
864 return result;
865 }
866
867 Py_DECREF_IMMORTAL(result);
868 }
869
870 int c;
871
872 if (PyInstance_Check(operand1)) {
873 cmpfunc fcmp = type1->tp_compare;
874 c = (*fcmp)(operand1, operand2);
875 } else if (0) {
876 cmpfunc fcmp = NULL;
877 c = (*fcmp)(operand1, operand2);
878 } else {
879 c = try_3way_compare(operand1, operand2);
880 }
881
882 if (c >= 2) {
883 if (type1 == &PyString_Type) {
884 Py_uintptr_t aa = (Py_uintptr_t)operand1;
885 Py_uintptr_t bb = (Py_uintptr_t)operand2;
886
887 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
888 } else if (operand1 == Py_None) {
889 // None is smaller than everything else
890 c = -1;
891 } else if (operand2 == Py_None) {
892 // None is smaller than everything else
893 c = 1;
894 } else if (PyNumber_Check(operand1)) {
895 // different type: compare type names but numbers are smaller than
896 // others.
897 if (PyNumber_Check(operand2)) {
898 // Both numbers, need to make a decision based on types.
899 Py_uintptr_t aa = (Py_uintptr_t)type1;
900 Py_uintptr_t bb = (Py_uintptr_t)&PyString_Type;
901
902 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
903 } else {
904 c = -1;
905 }
906 } else if (PyNumber_Check(operand2)) {
907 c = 1;
908 } else {
909 // Banking on C compile to optimize "strcmp".
910 int s = strcmp(type1->tp_name, "str");
911
912 if (s < 0) {
913 c = -1;
914 } else if (s > 0) {
915 c = 1;
916 } else {
917 // Same type name need to make a decision based on type address.
918 Py_uintptr_t aa = (Py_uintptr_t)type1;
919 Py_uintptr_t bb = (Py_uintptr_t)&PyString_Type;
920
921 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
922 }
923 }
924 }
925
926 Py_LeaveRecursiveCall();
927
928 if (unlikely(c <= -2)) {
929 return NULL;
930 }
931
932 switch (Py_GT) {
933 case Py_LT:
934 c = c < 0;
935 break;
936 case Py_LE:
937 c = c <= 0;
938 break;
939 case Py_EQ:
940 c = c == 0;
941 break;
942 case Py_NE:
943 c = c != 0;
944 break;
945 case Py_GT:
946 c = c > 0;
947 break;
948 case Py_GE:
949 c = c >= 0;
950 break;
951 }
952
953 bool r = c != 0;
954 PyObject *result = BOOL_FROM(r);
955 Py_INCREF_IMMORTAL(result);
956 return result;
957#else
958 bool checked_reverse_op = false;
959 richcmpfunc f;
960
961 if (type1 != &PyString_Type && Nuitka_Type_IsSubtype(&PyString_Type, type1)) {
962 f = PyString_Type.tp_richcompare;
963
964 if (f != NULL) {
965 checked_reverse_op = true;
966
967 PyObject *result = (*f)(operand2, operand1, Py_LT);
968
969 if (result != Py_NotImplemented) {
970 Py_LeaveRecursiveCall();
971
972 return result;
973 }
974
975 Py_DECREF_IMMORTAL(result);
976 }
977 }
978
979 f = TP_RICHCOMPARE(type1);
980
981 if (f != NULL) {
982 PyObject *result = (*f)(operand1, operand2, Py_GT);
983
984 if (result != Py_NotImplemented) {
985 Py_LeaveRecursiveCall();
986
987 return result;
988 }
989
990 Py_DECREF_IMMORTAL(result);
991 }
992
993 if (checked_reverse_op == false) {
994 f = PyString_Type.tp_richcompare;
995
996 if (f != NULL) {
997 PyObject *result = (*f)(operand2, operand1, Py_LT);
998
999 if (result != Py_NotImplemented) {
1000 Py_LeaveRecursiveCall();
1001
1002 return result;
1003 }
1004
1005 Py_DECREF_IMMORTAL(result);
1006 }
1007 }
1008
1009 Py_LeaveRecursiveCall();
1010
1011 // If it is not implemented, do pointer identity checks as "==" and "!=" and
1012 // otherwise give an error
1013 switch (Py_GT) {
1014 case Py_EQ: {
1015 bool r = operand1 == operand2;
1016 PyObject *result = BOOL_FROM(r);
1017 Py_INCREF_IMMORTAL(result);
1018 return result;
1019 }
1020 case Py_NE: {
1021 bool r = operand1 != operand2;
1022 PyObject *result = BOOL_FROM(r);
1023 Py_INCREF_IMMORTAL(result);
1024 return result;
1025 }
1026 default:
1027#if PYTHON_VERSION < 0x360
1028 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > str()", type1->tp_name);
1029#else
1030 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'str'", type1->tp_name);
1031#endif
1032 return NULL;
1033 }
1034#endif
1035}
1036#endif
1037
1038#if PYTHON_VERSION < 0x300
1039/* Code referring to "STR" corresponds to Python2 'str' and "OBJECT" to any Python object. */
1040PyObject *RICH_COMPARE_GT_OBJECT_STR_OBJECT(PyObject *operand1, PyObject *operand2) {
1041
1042 if (&PyString_Type == Py_TYPE(operand2)) {
1043 return COMPARE_GT_OBJECT_STR_STR(operand1, operand2);
1044 }
1045
1046#if PYTHON_VERSION < 0x300
1047 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
1048 return NULL;
1049 }
1050#else
1051 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
1052 return NULL;
1053 }
1054#endif
1055
1056 PyTypeObject *type2 = Py_TYPE(operand2);
1057
1058#if PYTHON_VERSION < 0x300
1059 // If the types are equal, we may get away immediately except for instances.
1060 if (&PyString_Type == type2 && !0) {
1061
1062 richcmpfunc frich = PyString_Type.tp_richcompare;
1063
1064 if (frich != NULL) {
1065 PyObject *result = (*frich)(operand1, operand2, Py_GT);
1066
1067 if (result != Py_NotImplemented) {
1068 Py_LeaveRecursiveCall();
1069
1070 return result;
1071 }
1072
1073 Py_DECREF_IMMORTAL(result);
1074 }
1075
1076 // No rich comparison worked, but maybe compare works.
1077 cmpfunc fcmp = NULL;
1078
1079 if (fcmp != NULL) {
1080 int c = (*fcmp)(operand1, operand2);
1081 c = adjust_tp_compare(c);
1082
1083 Py_LeaveRecursiveCall();
1084
1085 if (c == -2) {
1086 return NULL;
1087 }
1088
1089 switch (Py_GT) {
1090 case Py_LT:
1091 c = c < 0;
1092 break;
1093 case Py_LE:
1094 c = c <= 0;
1095 break;
1096 case Py_EQ:
1097 c = c == 0;
1098 break;
1099 case Py_NE:
1100 c = c != 0;
1101 break;
1102 case Py_GT:
1103 c = c > 0;
1104 break;
1105 case Py_GE:
1106 c = c >= 0;
1107 break;
1108 default:
1109 NUITKA_CANNOT_GET_HERE("wrong op_code");
1110 }
1111
1112 bool r = c != 0;
1113 PyObject *result = BOOL_FROM(r);
1114 Py_INCREF_IMMORTAL(result);
1115 return result;
1116 }
1117 }
1118
1119 // Fast path was not successful or not taken
1120 richcmpfunc f;
1121
1122 if (&PyString_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyString_Type)) {
1123 f = TP_RICHCOMPARE(type2);
1124
1125 if (f != NULL) {
1126 PyObject *result = (*f)(operand2, operand1, Py_LT);
1127
1128 if (result != Py_NotImplemented) {
1129 Py_LeaveRecursiveCall();
1130
1131 return result;
1132 }
1133
1134 Py_DECREF_IMMORTAL(result);
1135 }
1136 }
1137
1138 f = PyString_Type.tp_richcompare;
1139 if (f != NULL) {
1140 PyObject *result = (*f)(operand1, operand2, Py_GT);
1141
1142 if (result != Py_NotImplemented) {
1143 Py_LeaveRecursiveCall();
1144
1145 return result;
1146 }
1147
1148 Py_DECREF_IMMORTAL(result);
1149 }
1150
1151 f = TP_RICHCOMPARE(type2);
1152 if (f != NULL) {
1153 PyObject *result = (*f)(operand2, operand1, Py_LT);
1154
1155 if (result != Py_NotImplemented) {
1156 Py_LeaveRecursiveCall();
1157
1158 return result;
1159 }
1160
1161 Py_DECREF_IMMORTAL(result);
1162 }
1163
1164 int c;
1165
1166 if (0) {
1167 cmpfunc fcmp = NULL;
1168 c = (*fcmp)(operand1, operand2);
1169 } else if (PyInstance_Check(operand2)) {
1170 cmpfunc fcmp = type2->tp_compare;
1171 c = (*fcmp)(operand1, operand2);
1172 } else {
1173 c = try_3way_compare(operand1, operand2);
1174 }
1175
1176 if (c >= 2) {
1177 if (&PyString_Type == type2) {
1178 Py_uintptr_t aa = (Py_uintptr_t)operand1;
1179 Py_uintptr_t bb = (Py_uintptr_t)operand2;
1180
1181 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1182 } else if (operand1 == Py_None) {
1183 // None is smaller than everything else
1184 c = -1;
1185 } else if (operand2 == Py_None) {
1186 // None is smaller than everything else
1187 c = 1;
1188 } else if (PyNumber_Check(operand1)) {
1189 // different type: compare type names but numbers are smaller than
1190 // others.
1191 if (PyNumber_Check(operand2)) {
1192 // Both numbers, need to make a decision based on types.
1193 Py_uintptr_t aa = (Py_uintptr_t)&PyString_Type;
1194 Py_uintptr_t bb = (Py_uintptr_t)type2;
1195
1196 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1197 } else {
1198 c = -1;
1199 }
1200 } else if (PyNumber_Check(operand2)) {
1201 c = 1;
1202 } else {
1203 // Banking on C compile to optimize "strcmp".
1204 int s = strcmp("str", type2->tp_name);
1205
1206 if (s < 0) {
1207 c = -1;
1208 } else if (s > 0) {
1209 c = 1;
1210 } else {
1211 // Same type name need to make a decision based on type address.
1212 Py_uintptr_t aa = (Py_uintptr_t)&PyString_Type;
1213 Py_uintptr_t bb = (Py_uintptr_t)type2;
1214
1215 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1216 }
1217 }
1218 }
1219
1220 Py_LeaveRecursiveCall();
1221
1222 if (unlikely(c <= -2)) {
1223 return NULL;
1224 }
1225
1226 switch (Py_GT) {
1227 case Py_LT:
1228 c = c < 0;
1229 break;
1230 case Py_LE:
1231 c = c <= 0;
1232 break;
1233 case Py_EQ:
1234 c = c == 0;
1235 break;
1236 case Py_NE:
1237 c = c != 0;
1238 break;
1239 case Py_GT:
1240 c = c > 0;
1241 break;
1242 case Py_GE:
1243 c = c >= 0;
1244 break;
1245 }
1246
1247 bool r = c != 0;
1248 PyObject *result = BOOL_FROM(r);
1249 Py_INCREF_IMMORTAL(result);
1250 return result;
1251#else
1252 bool checked_reverse_op = false;
1253 richcmpfunc f;
1254
1255 if (&PyString_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyString_Type)) {
1256 f = TP_RICHCOMPARE(type2);
1257
1258 if (f != NULL) {
1259 checked_reverse_op = true;
1260
1261 PyObject *result = (*f)(operand2, operand1, Py_LT);
1262
1263 if (result != Py_NotImplemented) {
1264 Py_LeaveRecursiveCall();
1265
1266 return result;
1267 }
1268
1269 Py_DECREF_IMMORTAL(result);
1270 }
1271 }
1272
1273 f = PyString_Type.tp_richcompare;
1274
1275 if (f != NULL) {
1276 PyObject *result = (*f)(operand1, operand2, Py_GT);
1277
1278 if (result != Py_NotImplemented) {
1279 Py_LeaveRecursiveCall();
1280
1281 return result;
1282 }
1283
1284 Py_DECREF_IMMORTAL(result);
1285 }
1286
1287 if (checked_reverse_op == false) {
1288 f = TP_RICHCOMPARE(type2);
1289
1290 if (f != NULL) {
1291 PyObject *result = (*f)(operand2, operand1, Py_LT);
1292
1293 if (result != Py_NotImplemented) {
1294 Py_LeaveRecursiveCall();
1295
1296 return result;
1297 }
1298
1299 Py_DECREF_IMMORTAL(result);
1300 }
1301 }
1302
1303 Py_LeaveRecursiveCall();
1304
1305 // If it is not implemented, do pointer identity checks as "==" and "!=" and
1306 // otherwise give an error
1307 switch (Py_GT) {
1308 case Py_EQ: {
1309 bool r = operand1 == operand2;
1310 PyObject *result = BOOL_FROM(r);
1311 Py_INCREF_IMMORTAL(result);
1312 return result;
1313 }
1314 case Py_NE: {
1315 bool r = operand1 != operand2;
1316 PyObject *result = BOOL_FROM(r);
1317 Py_INCREF_IMMORTAL(result);
1318 return result;
1319 }
1320 default:
1321#if PYTHON_VERSION < 0x360
1322 PyErr_Format(PyExc_TypeError, "unorderable types: str() > %s()", type2->tp_name);
1323#else
1324 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'str' and '%s'", type2->tp_name);
1325#endif
1326 return NULL;
1327 }
1328#endif
1329}
1330#endif
1331
1332#if PYTHON_VERSION < 0x300
1333static bool COMPARE_GT_CBOOL_STR_STR(PyObject *operand1, PyObject *operand2) {
1334 CHECK_OBJECT(operand1);
1335 assert(PyString_CheckExact(operand1));
1336 CHECK_OBJECT(operand2);
1337 assert(PyString_CheckExact(operand2));
1338
1339 PyStringObject *a = (PyStringObject *)operand1;
1340 PyStringObject *b = (PyStringObject *)operand2;
1341
1342 // Same object has fast path for all operations.
1343 if (operand1 == operand2) {
1344 bool r = false;
1345
1346 // Convert to target type.
1347 bool result = r;
1348
1349 return result;
1350 }
1351
1352 Py_ssize_t len_a = Py_SIZE(operand1);
1353 Py_ssize_t len_b = Py_SIZE(operand2);
1354
1355 Py_ssize_t min_len = (len_a < len_b) ? len_a : len_b;
1356 int c;
1357
1358 if (min_len > 0) {
1359 c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
1360
1361 if (c == 0) {
1362 c = memcmp(a->ob_sval, b->ob_sval, min_len);
1363 }
1364 } else {
1365 c = 0;
1366 }
1367
1368 if (c == 0) {
1369 c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
1370 }
1371
1372 c = c > 0;
1373
1374 // Convert to target type.
1375 bool result = c != 0;
1376
1377 return result;
1378}
1379#endif
1380#if PYTHON_VERSION < 0x300
1381/* Code referring to "OBJECT" corresponds to any Python object and "STR" to Python2 'str'. */
1382nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_STR(PyObject *operand1, PyObject *operand2) {
1383
1384 if (Py_TYPE(operand1) == &PyString_Type) {
1385 return COMPARE_GT_CBOOL_STR_STR(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1386 }
1387
1388#if PYTHON_VERSION < 0x300
1389 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
1390 return NUITKA_BOOL_EXCEPTION;
1391 }
1392#else
1393 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
1394 return NUITKA_BOOL_EXCEPTION;
1395 }
1396#endif
1397
1398 PyTypeObject *type1 = Py_TYPE(operand1);
1399
1400#if PYTHON_VERSION < 0x300
1401 // If the types are equal, we may get away immediately except for instances.
1402 if (type1 == &PyString_Type && !0) {
1403
1404 richcmpfunc frich = PyString_Type.tp_richcompare;
1405
1406 if (frich != NULL) {
1407 PyObject *result = (*frich)(operand1, operand2, Py_GT);
1408
1409 if (result != Py_NotImplemented) {
1410 Py_LeaveRecursiveCall();
1411
1412 if (unlikely(result == NULL)) {
1413 return NUITKA_BOOL_EXCEPTION;
1414 }
1415
1416 {
1417 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1418 Py_DECREF(result);
1419 return r;
1420 }
1421 }
1422
1423 Py_DECREF_IMMORTAL(result);
1424 }
1425
1426 // No rich comparison worked, but maybe compare works.
1427 cmpfunc fcmp = NULL;
1428
1429 if (fcmp != NULL) {
1430 int c = (*fcmp)(operand1, operand2);
1431 c = adjust_tp_compare(c);
1432
1433 Py_LeaveRecursiveCall();
1434
1435 if (c == -2) {
1436 return NUITKA_BOOL_EXCEPTION;
1437 }
1438
1439 switch (Py_GT) {
1440 case Py_LT:
1441 c = c < 0;
1442 break;
1443 case Py_LE:
1444 c = c <= 0;
1445 break;
1446 case Py_EQ:
1447 c = c == 0;
1448 break;
1449 case Py_NE:
1450 c = c != 0;
1451 break;
1452 case Py_GT:
1453 c = c > 0;
1454 break;
1455 case Py_GE:
1456 c = c >= 0;
1457 break;
1458 default:
1459 NUITKA_CANNOT_GET_HERE("wrong op_code");
1460 }
1461
1462 bool r = c != 0;
1463 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1464
1465 return result;
1466 }
1467 }
1468
1469 // Fast path was not successful or not taken
1470 richcmpfunc f;
1471
1472 if (type1 != &PyString_Type && 0) {
1473 f = PyString_Type.tp_richcompare;
1474
1475 if (f != NULL) {
1476 PyObject *result = (*f)(operand2, operand1, Py_LT);
1477
1478 if (result != Py_NotImplemented) {
1479 Py_LeaveRecursiveCall();
1480
1481 if (unlikely(result == NULL)) {
1482 return NUITKA_BOOL_EXCEPTION;
1483 }
1484
1485 {
1486 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1487 Py_DECREF(result);
1488 return r;
1489 }
1490 }
1491
1492 Py_DECREF_IMMORTAL(result);
1493 }
1494 }
1495
1496 f = TP_RICHCOMPARE(type1);
1497 if (f != NULL) {
1498 PyObject *result = (*f)(operand1, operand2, Py_GT);
1499
1500 if (result != Py_NotImplemented) {
1501 Py_LeaveRecursiveCall();
1502
1503 if (unlikely(result == NULL)) {
1504 return NUITKA_BOOL_EXCEPTION;
1505 }
1506
1507 {
1508 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1509 Py_DECREF(result);
1510 return r;
1511 }
1512 }
1513
1514 Py_DECREF_IMMORTAL(result);
1515 }
1516
1517 f = PyString_Type.tp_richcompare;
1518 if (f != NULL) {
1519 PyObject *result = (*f)(operand2, operand1, Py_LT);
1520
1521 if (result != Py_NotImplemented) {
1522 Py_LeaveRecursiveCall();
1523
1524 if (unlikely(result == NULL)) {
1525 return NUITKA_BOOL_EXCEPTION;
1526 }
1527
1528 {
1529 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1530 Py_DECREF(result);
1531 return r;
1532 }
1533 }
1534
1535 Py_DECREF_IMMORTAL(result);
1536 }
1537
1538 int c;
1539
1540 if (PyInstance_Check(operand1)) {
1541 cmpfunc fcmp = type1->tp_compare;
1542 c = (*fcmp)(operand1, operand2);
1543 } else if (0) {
1544 cmpfunc fcmp = NULL;
1545 c = (*fcmp)(operand1, operand2);
1546 } else {
1547 c = try_3way_compare(operand1, operand2);
1548 }
1549
1550 if (c >= 2) {
1551 if (type1 == &PyString_Type) {
1552 Py_uintptr_t aa = (Py_uintptr_t)operand1;
1553 Py_uintptr_t bb = (Py_uintptr_t)operand2;
1554
1555 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1556 } else if (operand1 == Py_None) {
1557 // None is smaller than everything else
1558 c = -1;
1559 } else if (operand2 == Py_None) {
1560 // None is smaller than everything else
1561 c = 1;
1562 } else if (PyNumber_Check(operand1)) {
1563 // different type: compare type names but numbers are smaller than
1564 // others.
1565 if (PyNumber_Check(operand2)) {
1566 // Both numbers, need to make a decision based on types.
1567 Py_uintptr_t aa = (Py_uintptr_t)type1;
1568 Py_uintptr_t bb = (Py_uintptr_t)&PyString_Type;
1569
1570 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1571 } else {
1572 c = -1;
1573 }
1574 } else if (PyNumber_Check(operand2)) {
1575 c = 1;
1576 } else {
1577 // Banking on C compile to optimize "strcmp".
1578 int s = strcmp(type1->tp_name, "str");
1579
1580 if (s < 0) {
1581 c = -1;
1582 } else if (s > 0) {
1583 c = 1;
1584 } else {
1585 // Same type name need to make a decision based on type address.
1586 Py_uintptr_t aa = (Py_uintptr_t)type1;
1587 Py_uintptr_t bb = (Py_uintptr_t)&PyString_Type;
1588
1589 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1590 }
1591 }
1592 }
1593
1594 Py_LeaveRecursiveCall();
1595
1596 if (unlikely(c <= -2)) {
1597 return NUITKA_BOOL_EXCEPTION;
1598 }
1599
1600 switch (Py_GT) {
1601 case Py_LT:
1602 c = c < 0;
1603 break;
1604 case Py_LE:
1605 c = c <= 0;
1606 break;
1607 case Py_EQ:
1608 c = c == 0;
1609 break;
1610 case Py_NE:
1611 c = c != 0;
1612 break;
1613 case Py_GT:
1614 c = c > 0;
1615 break;
1616 case Py_GE:
1617 c = c >= 0;
1618 break;
1619 }
1620
1621 bool r = c != 0;
1622 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1623
1624 return result;
1625#else
1626 bool checked_reverse_op = false;
1627 richcmpfunc f;
1628
1629 if (type1 != &PyString_Type && Nuitka_Type_IsSubtype(&PyString_Type, type1)) {
1630 f = PyString_Type.tp_richcompare;
1631
1632 if (f != NULL) {
1633 checked_reverse_op = true;
1634
1635 PyObject *result = (*f)(operand2, operand1, Py_LT);
1636
1637 if (result != Py_NotImplemented) {
1638 Py_LeaveRecursiveCall();
1639
1640 if (unlikely(result == NULL)) {
1641 return NUITKA_BOOL_EXCEPTION;
1642 }
1643
1644 {
1645 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1646 Py_DECREF(result);
1647 return r;
1648 }
1649 }
1650
1651 Py_DECREF_IMMORTAL(result);
1652 }
1653 }
1654
1655 f = TP_RICHCOMPARE(type1);
1656
1657 if (f != NULL) {
1658 PyObject *result = (*f)(operand1, operand2, Py_GT);
1659
1660 if (result != Py_NotImplemented) {
1661 Py_LeaveRecursiveCall();
1662
1663 if (unlikely(result == NULL)) {
1664 return NUITKA_BOOL_EXCEPTION;
1665 }
1666
1667 {
1668 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1669 Py_DECREF(result);
1670 return r;
1671 }
1672 }
1673
1674 Py_DECREF_IMMORTAL(result);
1675 }
1676
1677 if (checked_reverse_op == false) {
1678 f = PyString_Type.tp_richcompare;
1679
1680 if (f != NULL) {
1681 PyObject *result = (*f)(operand2, operand1, Py_LT);
1682
1683 if (result != Py_NotImplemented) {
1684 Py_LeaveRecursiveCall();
1685
1686 if (unlikely(result == NULL)) {
1687 return NUITKA_BOOL_EXCEPTION;
1688 }
1689
1690 {
1691 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1692 Py_DECREF(result);
1693 return r;
1694 }
1695 }
1696
1697 Py_DECREF_IMMORTAL(result);
1698 }
1699 }
1700
1701 Py_LeaveRecursiveCall();
1702
1703 // If it is not implemented, do pointer identity checks as "==" and "!=" and
1704 // otherwise give an error
1705 switch (Py_GT) {
1706 case Py_EQ: {
1707 bool r = operand1 == operand2;
1708 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1709
1710 return result;
1711 }
1712 case Py_NE: {
1713 bool r = operand1 != operand2;
1714 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1715
1716 return result;
1717 }
1718 default:
1719#if PYTHON_VERSION < 0x360
1720 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > str()", type1->tp_name);
1721#else
1722 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'str'", type1->tp_name);
1723#endif
1724 return NUITKA_BOOL_EXCEPTION;
1725 }
1726#endif
1727}
1728#endif
1729
1730#if PYTHON_VERSION < 0x300
1731/* Code referring to "STR" corresponds to Python2 'str' and "OBJECT" to any Python object. */
1732nuitka_bool RICH_COMPARE_GT_NBOOL_STR_OBJECT(PyObject *operand1, PyObject *operand2) {
1733
1734 if (&PyString_Type == Py_TYPE(operand2)) {
1735 return COMPARE_GT_CBOOL_STR_STR(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1736 }
1737
1738#if PYTHON_VERSION < 0x300
1739 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
1740 return NUITKA_BOOL_EXCEPTION;
1741 }
1742#else
1743 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
1744 return NUITKA_BOOL_EXCEPTION;
1745 }
1746#endif
1747
1748 PyTypeObject *type2 = Py_TYPE(operand2);
1749
1750#if PYTHON_VERSION < 0x300
1751 // If the types are equal, we may get away immediately except for instances.
1752 if (&PyString_Type == type2 && !0) {
1753
1754 richcmpfunc frich = PyString_Type.tp_richcompare;
1755
1756 if (frich != NULL) {
1757 PyObject *result = (*frich)(operand1, operand2, Py_GT);
1758
1759 if (result != Py_NotImplemented) {
1760 Py_LeaveRecursiveCall();
1761
1762 if (unlikely(result == NULL)) {
1763 return NUITKA_BOOL_EXCEPTION;
1764 }
1765
1766 {
1767 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1768 Py_DECREF(result);
1769 return r;
1770 }
1771 }
1772
1773 Py_DECREF_IMMORTAL(result);
1774 }
1775
1776 // No rich comparison worked, but maybe compare works.
1777 cmpfunc fcmp = NULL;
1778
1779 if (fcmp != NULL) {
1780 int c = (*fcmp)(operand1, operand2);
1781 c = adjust_tp_compare(c);
1782
1783 Py_LeaveRecursiveCall();
1784
1785 if (c == -2) {
1786 return NUITKA_BOOL_EXCEPTION;
1787 }
1788
1789 switch (Py_GT) {
1790 case Py_LT:
1791 c = c < 0;
1792 break;
1793 case Py_LE:
1794 c = c <= 0;
1795 break;
1796 case Py_EQ:
1797 c = c == 0;
1798 break;
1799 case Py_NE:
1800 c = c != 0;
1801 break;
1802 case Py_GT:
1803 c = c > 0;
1804 break;
1805 case Py_GE:
1806 c = c >= 0;
1807 break;
1808 default:
1809 NUITKA_CANNOT_GET_HERE("wrong op_code");
1810 }
1811
1812 bool r = c != 0;
1813 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1814
1815 return result;
1816 }
1817 }
1818
1819 // Fast path was not successful or not taken
1820 richcmpfunc f;
1821
1822 if (&PyString_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyString_Type)) {
1823 f = TP_RICHCOMPARE(type2);
1824
1825 if (f != NULL) {
1826 PyObject *result = (*f)(operand2, operand1, Py_LT);
1827
1828 if (result != Py_NotImplemented) {
1829 Py_LeaveRecursiveCall();
1830
1831 if (unlikely(result == NULL)) {
1832 return NUITKA_BOOL_EXCEPTION;
1833 }
1834
1835 {
1836 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1837 Py_DECREF(result);
1838 return r;
1839 }
1840 }
1841
1842 Py_DECREF_IMMORTAL(result);
1843 }
1844 }
1845
1846 f = PyString_Type.tp_richcompare;
1847 if (f != NULL) {
1848 PyObject *result = (*f)(operand1, operand2, Py_GT);
1849
1850 if (result != Py_NotImplemented) {
1851 Py_LeaveRecursiveCall();
1852
1853 if (unlikely(result == NULL)) {
1854 return NUITKA_BOOL_EXCEPTION;
1855 }
1856
1857 {
1858 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1859 Py_DECREF(result);
1860 return r;
1861 }
1862 }
1863
1864 Py_DECREF_IMMORTAL(result);
1865 }
1866
1867 f = TP_RICHCOMPARE(type2);
1868 if (f != NULL) {
1869 PyObject *result = (*f)(operand2, operand1, Py_LT);
1870
1871 if (result != Py_NotImplemented) {
1872 Py_LeaveRecursiveCall();
1873
1874 if (unlikely(result == NULL)) {
1875 return NUITKA_BOOL_EXCEPTION;
1876 }
1877
1878 {
1879 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1880 Py_DECREF(result);
1881 return r;
1882 }
1883 }
1884
1885 Py_DECREF_IMMORTAL(result);
1886 }
1887
1888 int c;
1889
1890 if (0) {
1891 cmpfunc fcmp = NULL;
1892 c = (*fcmp)(operand1, operand2);
1893 } else if (PyInstance_Check(operand2)) {
1894 cmpfunc fcmp = type2->tp_compare;
1895 c = (*fcmp)(operand1, operand2);
1896 } else {
1897 c = try_3way_compare(operand1, operand2);
1898 }
1899
1900 if (c >= 2) {
1901 if (&PyString_Type == type2) {
1902 Py_uintptr_t aa = (Py_uintptr_t)operand1;
1903 Py_uintptr_t bb = (Py_uintptr_t)operand2;
1904
1905 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1906 } else if (operand1 == Py_None) {
1907 // None is smaller than everything else
1908 c = -1;
1909 } else if (operand2 == Py_None) {
1910 // None is smaller than everything else
1911 c = 1;
1912 } else if (PyNumber_Check(operand1)) {
1913 // different type: compare type names but numbers are smaller than
1914 // others.
1915 if (PyNumber_Check(operand2)) {
1916 // Both numbers, need to make a decision based on types.
1917 Py_uintptr_t aa = (Py_uintptr_t)&PyString_Type;
1918 Py_uintptr_t bb = (Py_uintptr_t)type2;
1919
1920 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1921 } else {
1922 c = -1;
1923 }
1924 } else if (PyNumber_Check(operand2)) {
1925 c = 1;
1926 } else {
1927 // Banking on C compile to optimize "strcmp".
1928 int s = strcmp("str", type2->tp_name);
1929
1930 if (s < 0) {
1931 c = -1;
1932 } else if (s > 0) {
1933 c = 1;
1934 } else {
1935 // Same type name need to make a decision based on type address.
1936 Py_uintptr_t aa = (Py_uintptr_t)&PyString_Type;
1937 Py_uintptr_t bb = (Py_uintptr_t)type2;
1938
1939 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
1940 }
1941 }
1942 }
1943
1944 Py_LeaveRecursiveCall();
1945
1946 if (unlikely(c <= -2)) {
1947 return NUITKA_BOOL_EXCEPTION;
1948 }
1949
1950 switch (Py_GT) {
1951 case Py_LT:
1952 c = c < 0;
1953 break;
1954 case Py_LE:
1955 c = c <= 0;
1956 break;
1957 case Py_EQ:
1958 c = c == 0;
1959 break;
1960 case Py_NE:
1961 c = c != 0;
1962 break;
1963 case Py_GT:
1964 c = c > 0;
1965 break;
1966 case Py_GE:
1967 c = c >= 0;
1968 break;
1969 }
1970
1971 bool r = c != 0;
1972 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1973
1974 return result;
1975#else
1976 bool checked_reverse_op = false;
1977 richcmpfunc f;
1978
1979 if (&PyString_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyString_Type)) {
1980 f = TP_RICHCOMPARE(type2);
1981
1982 if (f != NULL) {
1983 checked_reverse_op = true;
1984
1985 PyObject *result = (*f)(operand2, operand1, Py_LT);
1986
1987 if (result != Py_NotImplemented) {
1988 Py_LeaveRecursiveCall();
1989
1990 if (unlikely(result == NULL)) {
1991 return NUITKA_BOOL_EXCEPTION;
1992 }
1993
1994 {
1995 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
1996 Py_DECREF(result);
1997 return r;
1998 }
1999 }
2000
2001 Py_DECREF_IMMORTAL(result);
2002 }
2003 }
2004
2005 f = PyString_Type.tp_richcompare;
2006
2007 if (f != NULL) {
2008 PyObject *result = (*f)(operand1, operand2, Py_GT);
2009
2010 if (result != Py_NotImplemented) {
2011 Py_LeaveRecursiveCall();
2012
2013 if (unlikely(result == NULL)) {
2014 return NUITKA_BOOL_EXCEPTION;
2015 }
2016
2017 {
2018 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2019 Py_DECREF(result);
2020 return r;
2021 }
2022 }
2023
2024 Py_DECREF_IMMORTAL(result);
2025 }
2026
2027 if (checked_reverse_op == false) {
2028 f = TP_RICHCOMPARE(type2);
2029
2030 if (f != NULL) {
2031 PyObject *result = (*f)(operand2, operand1, Py_LT);
2032
2033 if (result != Py_NotImplemented) {
2034 Py_LeaveRecursiveCall();
2035
2036 if (unlikely(result == NULL)) {
2037 return NUITKA_BOOL_EXCEPTION;
2038 }
2039
2040 {
2041 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2042 Py_DECREF(result);
2043 return r;
2044 }
2045 }
2046
2047 Py_DECREF_IMMORTAL(result);
2048 }
2049 }
2050
2051 Py_LeaveRecursiveCall();
2052
2053 // If it is not implemented, do pointer identity checks as "==" and "!=" and
2054 // otherwise give an error
2055 switch (Py_GT) {
2056 case Py_EQ: {
2057 bool r = operand1 == operand2;
2058 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2059
2060 return result;
2061 }
2062 case Py_NE: {
2063 bool r = operand1 != operand2;
2064 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2065
2066 return result;
2067 }
2068 default:
2069#if PYTHON_VERSION < 0x360
2070 PyErr_Format(PyExc_TypeError, "unorderable types: str() > %s()", type2->tp_name);
2071#else
2072 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'str' and '%s'", type2->tp_name);
2073#endif
2074 return NUITKA_BOOL_EXCEPTION;
2075 }
2076#endif
2077}
2078#endif
2079
2080static PyObject *COMPARE_GT_OBJECT_UNICODE_UNICODE(PyObject *operand1, PyObject *operand2) {
2081 CHECK_OBJECT(operand1);
2082 assert(PyUnicode_CheckExact(operand1));
2083 CHECK_OBJECT(operand2);
2084 assert(PyUnicode_CheckExact(operand2));
2085
2086 PyUnicodeObject *a = (PyUnicodeObject *)operand1;
2087 PyUnicodeObject *b = (PyUnicodeObject *)operand2;
2088
2089 // Same object has fast path for all operations.
2090 if (operand1 == operand2) {
2091 bool r = false;
2092
2093 // Convert to target type.
2094 PyObject *result = BOOL_FROM(r);
2095 Py_INCREF_IMMORTAL(result);
2096 return result;
2097 }
2098
2099 PyObject *r = PyUnicode_RichCompare((PyObject *)a, (PyObject *)b, Py_GT);
2100 CHECK_OBJECT(r);
2101
2102 return r;
2103}
2104/* Code referring to "OBJECT" corresponds to any Python object and "UNICODE" to Python2 'unicode', Python3 'str'. */
2105PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_UNICODE(PyObject *operand1, PyObject *operand2) {
2106
2107 if (Py_TYPE(operand1) == &PyUnicode_Type) {
2108 return COMPARE_GT_OBJECT_UNICODE_UNICODE(operand1, operand2);
2109 }
2110
2111#if PYTHON_VERSION < 0x300
2112 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
2113 return NULL;
2114 }
2115#else
2116 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
2117 return NULL;
2118 }
2119#endif
2120
2121 PyTypeObject *type1 = Py_TYPE(operand1);
2122
2123#if PYTHON_VERSION < 0x300
2124 // If the types are equal, we may get away immediately except for instances.
2125 if (type1 == &PyUnicode_Type && !0) {
2126
2127 richcmpfunc frich = PyUnicode_Type.tp_richcompare;
2128
2129 if (frich != NULL) {
2130 PyObject *result = (*frich)(operand1, operand2, Py_GT);
2131
2132 if (result != Py_NotImplemented) {
2133 Py_LeaveRecursiveCall();
2134
2135 return result;
2136 }
2137
2138 Py_DECREF_IMMORTAL(result);
2139 }
2140
2141 // No rich comparison worked, but maybe compare works.
2142 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2143
2144 if (fcmp != NULL) {
2145 int c = (*fcmp)(operand1, operand2);
2146 c = adjust_tp_compare(c);
2147
2148 Py_LeaveRecursiveCall();
2149
2150 if (c == -2) {
2151 return NULL;
2152 }
2153
2154 switch (Py_GT) {
2155 case Py_LT:
2156 c = c < 0;
2157 break;
2158 case Py_LE:
2159 c = c <= 0;
2160 break;
2161 case Py_EQ:
2162 c = c == 0;
2163 break;
2164 case Py_NE:
2165 c = c != 0;
2166 break;
2167 case Py_GT:
2168 c = c > 0;
2169 break;
2170 case Py_GE:
2171 c = c >= 0;
2172 break;
2173 default:
2174 NUITKA_CANNOT_GET_HERE("wrong op_code");
2175 }
2176
2177 bool r = c != 0;
2178 PyObject *result = BOOL_FROM(r);
2179 Py_INCREF_IMMORTAL(result);
2180 return result;
2181 }
2182 }
2183
2184 // Fast path was not successful or not taken
2185 richcmpfunc f;
2186
2187 if (type1 != &PyUnicode_Type && 0) {
2188 f = PyUnicode_Type.tp_richcompare;
2189
2190 if (f != NULL) {
2191 PyObject *result = (*f)(operand2, operand1, Py_LT);
2192
2193 if (result != Py_NotImplemented) {
2194 Py_LeaveRecursiveCall();
2195
2196 return result;
2197 }
2198
2199 Py_DECREF_IMMORTAL(result);
2200 }
2201 }
2202
2203 f = TP_RICHCOMPARE(type1);
2204 if (f != NULL) {
2205 PyObject *result = (*f)(operand1, operand2, Py_GT);
2206
2207 if (result != Py_NotImplemented) {
2208 Py_LeaveRecursiveCall();
2209
2210 return result;
2211 }
2212
2213 Py_DECREF_IMMORTAL(result);
2214 }
2215
2216 f = PyUnicode_Type.tp_richcompare;
2217 if (f != NULL) {
2218 PyObject *result = (*f)(operand2, operand1, Py_LT);
2219
2220 if (result != Py_NotImplemented) {
2221 Py_LeaveRecursiveCall();
2222
2223 return result;
2224 }
2225
2226 Py_DECREF_IMMORTAL(result);
2227 }
2228
2229 int c;
2230
2231 if (PyInstance_Check(operand1)) {
2232 cmpfunc fcmp = type1->tp_compare;
2233 c = (*fcmp)(operand1, operand2);
2234 } else if (0) {
2235 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2236 c = (*fcmp)(operand1, operand2);
2237 } else {
2238 c = try_3way_compare(operand1, operand2);
2239 }
2240
2241 if (c >= 2) {
2242 if (type1 == &PyUnicode_Type) {
2243 Py_uintptr_t aa = (Py_uintptr_t)operand1;
2244 Py_uintptr_t bb = (Py_uintptr_t)operand2;
2245
2246 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2247 } else if (operand1 == Py_None) {
2248 // None is smaller than everything else
2249 c = -1;
2250 } else if (operand2 == Py_None) {
2251 // None is smaller than everything else
2252 c = 1;
2253 } else if (PyNumber_Check(operand1)) {
2254 // different type: compare type names but numbers are smaller than
2255 // others.
2256 if (PyNumber_Check(operand2)) {
2257 // Both numbers, need to make a decision based on types.
2258 Py_uintptr_t aa = (Py_uintptr_t)type1;
2259 Py_uintptr_t bb = (Py_uintptr_t)&PyUnicode_Type;
2260
2261 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2262 } else {
2263 c = -1;
2264 }
2265 } else if (PyNumber_Check(operand2)) {
2266 c = 1;
2267 } else {
2268 // Banking on C compile to optimize "strcmp".
2269 int s = strcmp(type1->tp_name, (PYTHON_VERSION < 0x300 ? "unicode" : "str"));
2270
2271 if (s < 0) {
2272 c = -1;
2273 } else if (s > 0) {
2274 c = 1;
2275 } else {
2276 // Same type name need to make a decision based on type address.
2277 Py_uintptr_t aa = (Py_uintptr_t)type1;
2278 Py_uintptr_t bb = (Py_uintptr_t)&PyUnicode_Type;
2279
2280 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2281 }
2282 }
2283 }
2284
2285 Py_LeaveRecursiveCall();
2286
2287 if (unlikely(c <= -2)) {
2288 return NULL;
2289 }
2290
2291 switch (Py_GT) {
2292 case Py_LT:
2293 c = c < 0;
2294 break;
2295 case Py_LE:
2296 c = c <= 0;
2297 break;
2298 case Py_EQ:
2299 c = c == 0;
2300 break;
2301 case Py_NE:
2302 c = c != 0;
2303 break;
2304 case Py_GT:
2305 c = c > 0;
2306 break;
2307 case Py_GE:
2308 c = c >= 0;
2309 break;
2310 }
2311
2312 bool r = c != 0;
2313 PyObject *result = BOOL_FROM(r);
2314 Py_INCREF_IMMORTAL(result);
2315 return result;
2316#else
2317 bool checked_reverse_op = false;
2318 richcmpfunc f;
2319
2320 if (type1 != &PyUnicode_Type && Nuitka_Type_IsSubtype(&PyUnicode_Type, type1)) {
2321 f = PyUnicode_Type.tp_richcompare;
2322
2323 if (f != NULL) {
2324 checked_reverse_op = true;
2325
2326 PyObject *result = (*f)(operand2, operand1, Py_LT);
2327
2328 if (result != Py_NotImplemented) {
2329 Py_LeaveRecursiveCall();
2330
2331 return result;
2332 }
2333
2334 Py_DECREF_IMMORTAL(result);
2335 }
2336 }
2337
2338 f = TP_RICHCOMPARE(type1);
2339
2340 if (f != NULL) {
2341 PyObject *result = (*f)(operand1, operand2, Py_GT);
2342
2343 if (result != Py_NotImplemented) {
2344 Py_LeaveRecursiveCall();
2345
2346 return result;
2347 }
2348
2349 Py_DECREF_IMMORTAL(result);
2350 }
2351
2352 if (checked_reverse_op == false) {
2353 f = PyUnicode_Type.tp_richcompare;
2354
2355 if (f != NULL) {
2356 PyObject *result = (*f)(operand2, operand1, Py_LT);
2357
2358 if (result != Py_NotImplemented) {
2359 Py_LeaveRecursiveCall();
2360
2361 return result;
2362 }
2363
2364 Py_DECREF_IMMORTAL(result);
2365 }
2366 }
2367
2368 Py_LeaveRecursiveCall();
2369
2370 // If it is not implemented, do pointer identity checks as "==" and "!=" and
2371 // otherwise give an error
2372 switch (Py_GT) {
2373 case Py_EQ: {
2374 bool r = operand1 == operand2;
2375 PyObject *result = BOOL_FROM(r);
2376 Py_INCREF_IMMORTAL(result);
2377 return result;
2378 }
2379 case Py_NE: {
2380 bool r = operand1 != operand2;
2381 PyObject *result = BOOL_FROM(r);
2382 Py_INCREF_IMMORTAL(result);
2383 return result;
2384 }
2385 default:
2386#if PYTHON_VERSION < 0x300
2387 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > unicode()", type1->tp_name);
2388#elif PYTHON_VERSION < 0x360
2389 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > str()", type1->tp_name);
2390#else
2391 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'str'", type1->tp_name);
2392#endif
2393 return NULL;
2394 }
2395#endif
2396}
2397
2398/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "OBJECT" to any Python object. */
2399PyObject *RICH_COMPARE_GT_OBJECT_UNICODE_OBJECT(PyObject *operand1, PyObject *operand2) {
2400
2401 if (&PyUnicode_Type == Py_TYPE(operand2)) {
2402 return COMPARE_GT_OBJECT_UNICODE_UNICODE(operand1, operand2);
2403 }
2404
2405#if PYTHON_VERSION < 0x300
2406 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
2407 return NULL;
2408 }
2409#else
2410 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
2411 return NULL;
2412 }
2413#endif
2414
2415 PyTypeObject *type2 = Py_TYPE(operand2);
2416
2417#if PYTHON_VERSION < 0x300
2418 // If the types are equal, we may get away immediately except for instances.
2419 if (&PyUnicode_Type == type2 && !0) {
2420
2421 richcmpfunc frich = PyUnicode_Type.tp_richcompare;
2422
2423 if (frich != NULL) {
2424 PyObject *result = (*frich)(operand1, operand2, Py_GT);
2425
2426 if (result != Py_NotImplemented) {
2427 Py_LeaveRecursiveCall();
2428
2429 return result;
2430 }
2431
2432 Py_DECREF_IMMORTAL(result);
2433 }
2434
2435 // No rich comparison worked, but maybe compare works.
2436 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2437
2438 if (fcmp != NULL) {
2439 int c = (*fcmp)(operand1, operand2);
2440 c = adjust_tp_compare(c);
2441
2442 Py_LeaveRecursiveCall();
2443
2444 if (c == -2) {
2445 return NULL;
2446 }
2447
2448 switch (Py_GT) {
2449 case Py_LT:
2450 c = c < 0;
2451 break;
2452 case Py_LE:
2453 c = c <= 0;
2454 break;
2455 case Py_EQ:
2456 c = c == 0;
2457 break;
2458 case Py_NE:
2459 c = c != 0;
2460 break;
2461 case Py_GT:
2462 c = c > 0;
2463 break;
2464 case Py_GE:
2465 c = c >= 0;
2466 break;
2467 default:
2468 NUITKA_CANNOT_GET_HERE("wrong op_code");
2469 }
2470
2471 bool r = c != 0;
2472 PyObject *result = BOOL_FROM(r);
2473 Py_INCREF_IMMORTAL(result);
2474 return result;
2475 }
2476 }
2477
2478 // Fast path was not successful or not taken
2479 richcmpfunc f;
2480
2481 if (&PyUnicode_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyUnicode_Type)) {
2482 f = TP_RICHCOMPARE(type2);
2483
2484 if (f != NULL) {
2485 PyObject *result = (*f)(operand2, operand1, Py_LT);
2486
2487 if (result != Py_NotImplemented) {
2488 Py_LeaveRecursiveCall();
2489
2490 return result;
2491 }
2492
2493 Py_DECREF_IMMORTAL(result);
2494 }
2495 }
2496
2497 f = PyUnicode_Type.tp_richcompare;
2498 if (f != NULL) {
2499 PyObject *result = (*f)(operand1, operand2, Py_GT);
2500
2501 if (result != Py_NotImplemented) {
2502 Py_LeaveRecursiveCall();
2503
2504 return result;
2505 }
2506
2507 Py_DECREF_IMMORTAL(result);
2508 }
2509
2510 f = TP_RICHCOMPARE(type2);
2511 if (f != NULL) {
2512 PyObject *result = (*f)(operand2, operand1, Py_LT);
2513
2514 if (result != Py_NotImplemented) {
2515 Py_LeaveRecursiveCall();
2516
2517 return result;
2518 }
2519
2520 Py_DECREF_IMMORTAL(result);
2521 }
2522
2523 int c;
2524
2525 if (0) {
2526 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2527 c = (*fcmp)(operand1, operand2);
2528 } else if (PyInstance_Check(operand2)) {
2529 cmpfunc fcmp = type2->tp_compare;
2530 c = (*fcmp)(operand1, operand2);
2531 } else {
2532 c = try_3way_compare(operand1, operand2);
2533 }
2534
2535 if (c >= 2) {
2536 if (&PyUnicode_Type == type2) {
2537 Py_uintptr_t aa = (Py_uintptr_t)operand1;
2538 Py_uintptr_t bb = (Py_uintptr_t)operand2;
2539
2540 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2541 } else if (operand1 == Py_None) {
2542 // None is smaller than everything else
2543 c = -1;
2544 } else if (operand2 == Py_None) {
2545 // None is smaller than everything else
2546 c = 1;
2547 } else if (PyNumber_Check(operand1)) {
2548 // different type: compare type names but numbers are smaller than
2549 // others.
2550 if (PyNumber_Check(operand2)) {
2551 // Both numbers, need to make a decision based on types.
2552 Py_uintptr_t aa = (Py_uintptr_t)&PyUnicode_Type;
2553 Py_uintptr_t bb = (Py_uintptr_t)type2;
2554
2555 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2556 } else {
2557 c = -1;
2558 }
2559 } else if (PyNumber_Check(operand2)) {
2560 c = 1;
2561 } else {
2562 // Banking on C compile to optimize "strcmp".
2563 int s = strcmp((PYTHON_VERSION < 0x300 ? "unicode" : "str"), type2->tp_name);
2564
2565 if (s < 0) {
2566 c = -1;
2567 } else if (s > 0) {
2568 c = 1;
2569 } else {
2570 // Same type name need to make a decision based on type address.
2571 Py_uintptr_t aa = (Py_uintptr_t)&PyUnicode_Type;
2572 Py_uintptr_t bb = (Py_uintptr_t)type2;
2573
2574 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2575 }
2576 }
2577 }
2578
2579 Py_LeaveRecursiveCall();
2580
2581 if (unlikely(c <= -2)) {
2582 return NULL;
2583 }
2584
2585 switch (Py_GT) {
2586 case Py_LT:
2587 c = c < 0;
2588 break;
2589 case Py_LE:
2590 c = c <= 0;
2591 break;
2592 case Py_EQ:
2593 c = c == 0;
2594 break;
2595 case Py_NE:
2596 c = c != 0;
2597 break;
2598 case Py_GT:
2599 c = c > 0;
2600 break;
2601 case Py_GE:
2602 c = c >= 0;
2603 break;
2604 }
2605
2606 bool r = c != 0;
2607 PyObject *result = BOOL_FROM(r);
2608 Py_INCREF_IMMORTAL(result);
2609 return result;
2610#else
2611 bool checked_reverse_op = false;
2612 richcmpfunc f;
2613
2614 if (&PyUnicode_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyUnicode_Type)) {
2615 f = TP_RICHCOMPARE(type2);
2616
2617 if (f != NULL) {
2618 checked_reverse_op = true;
2619
2620 PyObject *result = (*f)(operand2, operand1, Py_LT);
2621
2622 if (result != Py_NotImplemented) {
2623 Py_LeaveRecursiveCall();
2624
2625 return result;
2626 }
2627
2628 Py_DECREF_IMMORTAL(result);
2629 }
2630 }
2631
2632 f = PyUnicode_Type.tp_richcompare;
2633
2634 if (f != NULL) {
2635 PyObject *result = (*f)(operand1, operand2, Py_GT);
2636
2637 if (result != Py_NotImplemented) {
2638 Py_LeaveRecursiveCall();
2639
2640 return result;
2641 }
2642
2643 Py_DECREF_IMMORTAL(result);
2644 }
2645
2646 if (checked_reverse_op == false) {
2647 f = TP_RICHCOMPARE(type2);
2648
2649 if (f != NULL) {
2650 PyObject *result = (*f)(operand2, operand1, Py_LT);
2651
2652 if (result != Py_NotImplemented) {
2653 Py_LeaveRecursiveCall();
2654
2655 return result;
2656 }
2657
2658 Py_DECREF_IMMORTAL(result);
2659 }
2660 }
2661
2662 Py_LeaveRecursiveCall();
2663
2664 // If it is not implemented, do pointer identity checks as "==" and "!=" and
2665 // otherwise give an error
2666 switch (Py_GT) {
2667 case Py_EQ: {
2668 bool r = operand1 == operand2;
2669 PyObject *result = BOOL_FROM(r);
2670 Py_INCREF_IMMORTAL(result);
2671 return result;
2672 }
2673 case Py_NE: {
2674 bool r = operand1 != operand2;
2675 PyObject *result = BOOL_FROM(r);
2676 Py_INCREF_IMMORTAL(result);
2677 return result;
2678 }
2679 default:
2680#if PYTHON_VERSION < 0x300
2681 PyErr_Format(PyExc_TypeError, "unorderable types: unicode() > %s()", type2->tp_name);
2682#elif PYTHON_VERSION < 0x360
2683 PyErr_Format(PyExc_TypeError, "unorderable types: str() > %s()", type2->tp_name);
2684#else
2685 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'str' and '%s'", type2->tp_name);
2686#endif
2687 return NULL;
2688 }
2689#endif
2690}
2691
2692static bool COMPARE_GT_CBOOL_UNICODE_UNICODE(PyObject *operand1, PyObject *operand2) {
2693 CHECK_OBJECT(operand1);
2694 assert(PyUnicode_CheckExact(operand1));
2695 CHECK_OBJECT(operand2);
2696 assert(PyUnicode_CheckExact(operand2));
2697
2698 PyUnicodeObject *a = (PyUnicodeObject *)operand1;
2699 PyUnicodeObject *b = (PyUnicodeObject *)operand2;
2700
2701 // Same object has fast path for all operations.
2702 if (operand1 == operand2) {
2703 bool r = false;
2704
2705 // Convert to target type.
2706 bool result = r;
2707
2708 return result;
2709 }
2710
2711 PyObject *r = PyUnicode_RichCompare((PyObject *)a, (PyObject *)b, Py_GT);
2712 CHECK_OBJECT(r);
2713
2714 // Convert to target type if necessary
2715 bool result = r == Py_True;
2716 Py_DECREF_IMMORTAL(r);
2717
2718 return result;
2719}
2720/* Code referring to "OBJECT" corresponds to any Python object and "UNICODE" to Python2 'unicode', Python3 'str'. */
2721nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_UNICODE(PyObject *operand1, PyObject *operand2) {
2722
2723 if (Py_TYPE(operand1) == &PyUnicode_Type) {
2724 return COMPARE_GT_CBOOL_UNICODE_UNICODE(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2725 }
2726
2727#if PYTHON_VERSION < 0x300
2728 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
2729 return NUITKA_BOOL_EXCEPTION;
2730 }
2731#else
2732 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
2733 return NUITKA_BOOL_EXCEPTION;
2734 }
2735#endif
2736
2737 PyTypeObject *type1 = Py_TYPE(operand1);
2738
2739#if PYTHON_VERSION < 0x300
2740 // If the types are equal, we may get away immediately except for instances.
2741 if (type1 == &PyUnicode_Type && !0) {
2742
2743 richcmpfunc frich = PyUnicode_Type.tp_richcompare;
2744
2745 if (frich != NULL) {
2746 PyObject *result = (*frich)(operand1, operand2, Py_GT);
2747
2748 if (result != Py_NotImplemented) {
2749 Py_LeaveRecursiveCall();
2750
2751 if (unlikely(result == NULL)) {
2752 return NUITKA_BOOL_EXCEPTION;
2753 }
2754
2755 {
2756 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2757 Py_DECREF(result);
2758 return r;
2759 }
2760 }
2761
2762 Py_DECREF_IMMORTAL(result);
2763 }
2764
2765 // No rich comparison worked, but maybe compare works.
2766 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2767
2768 if (fcmp != NULL) {
2769 int c = (*fcmp)(operand1, operand2);
2770 c = adjust_tp_compare(c);
2771
2772 Py_LeaveRecursiveCall();
2773
2774 if (c == -2) {
2775 return NUITKA_BOOL_EXCEPTION;
2776 }
2777
2778 switch (Py_GT) {
2779 case Py_LT:
2780 c = c < 0;
2781 break;
2782 case Py_LE:
2783 c = c <= 0;
2784 break;
2785 case Py_EQ:
2786 c = c == 0;
2787 break;
2788 case Py_NE:
2789 c = c != 0;
2790 break;
2791 case Py_GT:
2792 c = c > 0;
2793 break;
2794 case Py_GE:
2795 c = c >= 0;
2796 break;
2797 default:
2798 NUITKA_CANNOT_GET_HERE("wrong op_code");
2799 }
2800
2801 bool r = c != 0;
2802 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2803
2804 return result;
2805 }
2806 }
2807
2808 // Fast path was not successful or not taken
2809 richcmpfunc f;
2810
2811 if (type1 != &PyUnicode_Type && 0) {
2812 f = PyUnicode_Type.tp_richcompare;
2813
2814 if (f != NULL) {
2815 PyObject *result = (*f)(operand2, operand1, Py_LT);
2816
2817 if (result != Py_NotImplemented) {
2818 Py_LeaveRecursiveCall();
2819
2820 if (unlikely(result == NULL)) {
2821 return NUITKA_BOOL_EXCEPTION;
2822 }
2823
2824 {
2825 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2826 Py_DECREF(result);
2827 return r;
2828 }
2829 }
2830
2831 Py_DECREF_IMMORTAL(result);
2832 }
2833 }
2834
2835 f = TP_RICHCOMPARE(type1);
2836 if (f != NULL) {
2837 PyObject *result = (*f)(operand1, operand2, Py_GT);
2838
2839 if (result != Py_NotImplemented) {
2840 Py_LeaveRecursiveCall();
2841
2842 if (unlikely(result == NULL)) {
2843 return NUITKA_BOOL_EXCEPTION;
2844 }
2845
2846 {
2847 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2848 Py_DECREF(result);
2849 return r;
2850 }
2851 }
2852
2853 Py_DECREF_IMMORTAL(result);
2854 }
2855
2856 f = PyUnicode_Type.tp_richcompare;
2857 if (f != NULL) {
2858 PyObject *result = (*f)(operand2, operand1, Py_LT);
2859
2860 if (result != Py_NotImplemented) {
2861 Py_LeaveRecursiveCall();
2862
2863 if (unlikely(result == NULL)) {
2864 return NUITKA_BOOL_EXCEPTION;
2865 }
2866
2867 {
2868 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2869 Py_DECREF(result);
2870 return r;
2871 }
2872 }
2873
2874 Py_DECREF_IMMORTAL(result);
2875 }
2876
2877 int c;
2878
2879 if (PyInstance_Check(operand1)) {
2880 cmpfunc fcmp = type1->tp_compare;
2881 c = (*fcmp)(operand1, operand2);
2882 } else if (0) {
2883 cmpfunc fcmp = PyUnicode_Type.tp_compare;
2884 c = (*fcmp)(operand1, operand2);
2885 } else {
2886 c = try_3way_compare(operand1, operand2);
2887 }
2888
2889 if (c >= 2) {
2890 if (type1 == &PyUnicode_Type) {
2891 Py_uintptr_t aa = (Py_uintptr_t)operand1;
2892 Py_uintptr_t bb = (Py_uintptr_t)operand2;
2893
2894 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2895 } else if (operand1 == Py_None) {
2896 // None is smaller than everything else
2897 c = -1;
2898 } else if (operand2 == Py_None) {
2899 // None is smaller than everything else
2900 c = 1;
2901 } else if (PyNumber_Check(operand1)) {
2902 // different type: compare type names but numbers are smaller than
2903 // others.
2904 if (PyNumber_Check(operand2)) {
2905 // Both numbers, need to make a decision based on types.
2906 Py_uintptr_t aa = (Py_uintptr_t)type1;
2907 Py_uintptr_t bb = (Py_uintptr_t)&PyUnicode_Type;
2908
2909 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2910 } else {
2911 c = -1;
2912 }
2913 } else if (PyNumber_Check(operand2)) {
2914 c = 1;
2915 } else {
2916 // Banking on C compile to optimize "strcmp".
2917 int s = strcmp(type1->tp_name, (PYTHON_VERSION < 0x300 ? "unicode" : "str"));
2918
2919 if (s < 0) {
2920 c = -1;
2921 } else if (s > 0) {
2922 c = 1;
2923 } else {
2924 // Same type name need to make a decision based on type address.
2925 Py_uintptr_t aa = (Py_uintptr_t)type1;
2926 Py_uintptr_t bb = (Py_uintptr_t)&PyUnicode_Type;
2927
2928 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
2929 }
2930 }
2931 }
2932
2933 Py_LeaveRecursiveCall();
2934
2935 if (unlikely(c <= -2)) {
2936 return NUITKA_BOOL_EXCEPTION;
2937 }
2938
2939 switch (Py_GT) {
2940 case Py_LT:
2941 c = c < 0;
2942 break;
2943 case Py_LE:
2944 c = c <= 0;
2945 break;
2946 case Py_EQ:
2947 c = c == 0;
2948 break;
2949 case Py_NE:
2950 c = c != 0;
2951 break;
2952 case Py_GT:
2953 c = c > 0;
2954 break;
2955 case Py_GE:
2956 c = c >= 0;
2957 break;
2958 }
2959
2960 bool r = c != 0;
2961 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2962
2963 return result;
2964#else
2965 bool checked_reverse_op = false;
2966 richcmpfunc f;
2967
2968 if (type1 != &PyUnicode_Type && Nuitka_Type_IsSubtype(&PyUnicode_Type, type1)) {
2969 f = PyUnicode_Type.tp_richcompare;
2970
2971 if (f != NULL) {
2972 checked_reverse_op = true;
2973
2974 PyObject *result = (*f)(operand2, operand1, Py_LT);
2975
2976 if (result != Py_NotImplemented) {
2977 Py_LeaveRecursiveCall();
2978
2979 if (unlikely(result == NULL)) {
2980 return NUITKA_BOOL_EXCEPTION;
2981 }
2982
2983 {
2984 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
2985 Py_DECREF(result);
2986 return r;
2987 }
2988 }
2989
2990 Py_DECREF_IMMORTAL(result);
2991 }
2992 }
2993
2994 f = TP_RICHCOMPARE(type1);
2995
2996 if (f != NULL) {
2997 PyObject *result = (*f)(operand1, operand2, Py_GT);
2998
2999 if (result != Py_NotImplemented) {
3000 Py_LeaveRecursiveCall();
3001
3002 if (unlikely(result == NULL)) {
3003 return NUITKA_BOOL_EXCEPTION;
3004 }
3005
3006 {
3007 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3008 Py_DECREF(result);
3009 return r;
3010 }
3011 }
3012
3013 Py_DECREF_IMMORTAL(result);
3014 }
3015
3016 if (checked_reverse_op == false) {
3017 f = PyUnicode_Type.tp_richcompare;
3018
3019 if (f != NULL) {
3020 PyObject *result = (*f)(operand2, operand1, Py_LT);
3021
3022 if (result != Py_NotImplemented) {
3023 Py_LeaveRecursiveCall();
3024
3025 if (unlikely(result == NULL)) {
3026 return NUITKA_BOOL_EXCEPTION;
3027 }
3028
3029 {
3030 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3031 Py_DECREF(result);
3032 return r;
3033 }
3034 }
3035
3036 Py_DECREF_IMMORTAL(result);
3037 }
3038 }
3039
3040 Py_LeaveRecursiveCall();
3041
3042 // If it is not implemented, do pointer identity checks as "==" and "!=" and
3043 // otherwise give an error
3044 switch (Py_GT) {
3045 case Py_EQ: {
3046 bool r = operand1 == operand2;
3047 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3048
3049 return result;
3050 }
3051 case Py_NE: {
3052 bool r = operand1 != operand2;
3053 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3054
3055 return result;
3056 }
3057 default:
3058#if PYTHON_VERSION < 0x300
3059 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > unicode()", type1->tp_name);
3060#elif PYTHON_VERSION < 0x360
3061 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > str()", type1->tp_name);
3062#else
3063 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'str'", type1->tp_name);
3064#endif
3065 return NUITKA_BOOL_EXCEPTION;
3066 }
3067#endif
3068}
3069
3070/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "OBJECT" to any Python object. */
3071nuitka_bool RICH_COMPARE_GT_NBOOL_UNICODE_OBJECT(PyObject *operand1, PyObject *operand2) {
3072
3073 if (&PyUnicode_Type == Py_TYPE(operand2)) {
3074 return COMPARE_GT_CBOOL_UNICODE_UNICODE(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3075 }
3076
3077#if PYTHON_VERSION < 0x300
3078 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
3079 return NUITKA_BOOL_EXCEPTION;
3080 }
3081#else
3082 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
3083 return NUITKA_BOOL_EXCEPTION;
3084 }
3085#endif
3086
3087 PyTypeObject *type2 = Py_TYPE(operand2);
3088
3089#if PYTHON_VERSION < 0x300
3090 // If the types are equal, we may get away immediately except for instances.
3091 if (&PyUnicode_Type == type2 && !0) {
3092
3093 richcmpfunc frich = PyUnicode_Type.tp_richcompare;
3094
3095 if (frich != NULL) {
3096 PyObject *result = (*frich)(operand1, operand2, Py_GT);
3097
3098 if (result != Py_NotImplemented) {
3099 Py_LeaveRecursiveCall();
3100
3101 if (unlikely(result == NULL)) {
3102 return NUITKA_BOOL_EXCEPTION;
3103 }
3104
3105 {
3106 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3107 Py_DECREF(result);
3108 return r;
3109 }
3110 }
3111
3112 Py_DECREF_IMMORTAL(result);
3113 }
3114
3115 // No rich comparison worked, but maybe compare works.
3116 cmpfunc fcmp = PyUnicode_Type.tp_compare;
3117
3118 if (fcmp != NULL) {
3119 int c = (*fcmp)(operand1, operand2);
3120 c = adjust_tp_compare(c);
3121
3122 Py_LeaveRecursiveCall();
3123
3124 if (c == -2) {
3125 return NUITKA_BOOL_EXCEPTION;
3126 }
3127
3128 switch (Py_GT) {
3129 case Py_LT:
3130 c = c < 0;
3131 break;
3132 case Py_LE:
3133 c = c <= 0;
3134 break;
3135 case Py_EQ:
3136 c = c == 0;
3137 break;
3138 case Py_NE:
3139 c = c != 0;
3140 break;
3141 case Py_GT:
3142 c = c > 0;
3143 break;
3144 case Py_GE:
3145 c = c >= 0;
3146 break;
3147 default:
3148 NUITKA_CANNOT_GET_HERE("wrong op_code");
3149 }
3150
3151 bool r = c != 0;
3152 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3153
3154 return result;
3155 }
3156 }
3157
3158 // Fast path was not successful or not taken
3159 richcmpfunc f;
3160
3161 if (&PyUnicode_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyUnicode_Type)) {
3162 f = TP_RICHCOMPARE(type2);
3163
3164 if (f != NULL) {
3165 PyObject *result = (*f)(operand2, operand1, Py_LT);
3166
3167 if (result != Py_NotImplemented) {
3168 Py_LeaveRecursiveCall();
3169
3170 if (unlikely(result == NULL)) {
3171 return NUITKA_BOOL_EXCEPTION;
3172 }
3173
3174 {
3175 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3176 Py_DECREF(result);
3177 return r;
3178 }
3179 }
3180
3181 Py_DECREF_IMMORTAL(result);
3182 }
3183 }
3184
3185 f = PyUnicode_Type.tp_richcompare;
3186 if (f != NULL) {
3187 PyObject *result = (*f)(operand1, operand2, Py_GT);
3188
3189 if (result != Py_NotImplemented) {
3190 Py_LeaveRecursiveCall();
3191
3192 if (unlikely(result == NULL)) {
3193 return NUITKA_BOOL_EXCEPTION;
3194 }
3195
3196 {
3197 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3198 Py_DECREF(result);
3199 return r;
3200 }
3201 }
3202
3203 Py_DECREF_IMMORTAL(result);
3204 }
3205
3206 f = TP_RICHCOMPARE(type2);
3207 if (f != NULL) {
3208 PyObject *result = (*f)(operand2, operand1, Py_LT);
3209
3210 if (result != Py_NotImplemented) {
3211 Py_LeaveRecursiveCall();
3212
3213 if (unlikely(result == NULL)) {
3214 return NUITKA_BOOL_EXCEPTION;
3215 }
3216
3217 {
3218 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3219 Py_DECREF(result);
3220 return r;
3221 }
3222 }
3223
3224 Py_DECREF_IMMORTAL(result);
3225 }
3226
3227 int c;
3228
3229 if (0) {
3230 cmpfunc fcmp = PyUnicode_Type.tp_compare;
3231 c = (*fcmp)(operand1, operand2);
3232 } else if (PyInstance_Check(operand2)) {
3233 cmpfunc fcmp = type2->tp_compare;
3234 c = (*fcmp)(operand1, operand2);
3235 } else {
3236 c = try_3way_compare(operand1, operand2);
3237 }
3238
3239 if (c >= 2) {
3240 if (&PyUnicode_Type == type2) {
3241 Py_uintptr_t aa = (Py_uintptr_t)operand1;
3242 Py_uintptr_t bb = (Py_uintptr_t)operand2;
3243
3244 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3245 } else if (operand1 == Py_None) {
3246 // None is smaller than everything else
3247 c = -1;
3248 } else if (operand2 == Py_None) {
3249 // None is smaller than everything else
3250 c = 1;
3251 } else if (PyNumber_Check(operand1)) {
3252 // different type: compare type names but numbers are smaller than
3253 // others.
3254 if (PyNumber_Check(operand2)) {
3255 // Both numbers, need to make a decision based on types.
3256 Py_uintptr_t aa = (Py_uintptr_t)&PyUnicode_Type;
3257 Py_uintptr_t bb = (Py_uintptr_t)type2;
3258
3259 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3260 } else {
3261 c = -1;
3262 }
3263 } else if (PyNumber_Check(operand2)) {
3264 c = 1;
3265 } else {
3266 // Banking on C compile to optimize "strcmp".
3267 int s = strcmp((PYTHON_VERSION < 0x300 ? "unicode" : "str"), type2->tp_name);
3268
3269 if (s < 0) {
3270 c = -1;
3271 } else if (s > 0) {
3272 c = 1;
3273 } else {
3274 // Same type name need to make a decision based on type address.
3275 Py_uintptr_t aa = (Py_uintptr_t)&PyUnicode_Type;
3276 Py_uintptr_t bb = (Py_uintptr_t)type2;
3277
3278 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3279 }
3280 }
3281 }
3282
3283 Py_LeaveRecursiveCall();
3284
3285 if (unlikely(c <= -2)) {
3286 return NUITKA_BOOL_EXCEPTION;
3287 }
3288
3289 switch (Py_GT) {
3290 case Py_LT:
3291 c = c < 0;
3292 break;
3293 case Py_LE:
3294 c = c <= 0;
3295 break;
3296 case Py_EQ:
3297 c = c == 0;
3298 break;
3299 case Py_NE:
3300 c = c != 0;
3301 break;
3302 case Py_GT:
3303 c = c > 0;
3304 break;
3305 case Py_GE:
3306 c = c >= 0;
3307 break;
3308 }
3309
3310 bool r = c != 0;
3311 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3312
3313 return result;
3314#else
3315 bool checked_reverse_op = false;
3316 richcmpfunc f;
3317
3318 if (&PyUnicode_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyUnicode_Type)) {
3319 f = TP_RICHCOMPARE(type2);
3320
3321 if (f != NULL) {
3322 checked_reverse_op = true;
3323
3324 PyObject *result = (*f)(operand2, operand1, Py_LT);
3325
3326 if (result != Py_NotImplemented) {
3327 Py_LeaveRecursiveCall();
3328
3329 if (unlikely(result == NULL)) {
3330 return NUITKA_BOOL_EXCEPTION;
3331 }
3332
3333 {
3334 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3335 Py_DECREF(result);
3336 return r;
3337 }
3338 }
3339
3340 Py_DECREF_IMMORTAL(result);
3341 }
3342 }
3343
3344 f = PyUnicode_Type.tp_richcompare;
3345
3346 if (f != NULL) {
3347 PyObject *result = (*f)(operand1, operand2, Py_GT);
3348
3349 if (result != Py_NotImplemented) {
3350 Py_LeaveRecursiveCall();
3351
3352 if (unlikely(result == NULL)) {
3353 return NUITKA_BOOL_EXCEPTION;
3354 }
3355
3356 {
3357 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3358 Py_DECREF(result);
3359 return r;
3360 }
3361 }
3362
3363 Py_DECREF_IMMORTAL(result);
3364 }
3365
3366 if (checked_reverse_op == false) {
3367 f = TP_RICHCOMPARE(type2);
3368
3369 if (f != NULL) {
3370 PyObject *result = (*f)(operand2, operand1, Py_LT);
3371
3372 if (result != Py_NotImplemented) {
3373 Py_LeaveRecursiveCall();
3374
3375 if (unlikely(result == NULL)) {
3376 return NUITKA_BOOL_EXCEPTION;
3377 }
3378
3379 {
3380 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3381 Py_DECREF(result);
3382 return r;
3383 }
3384 }
3385
3386 Py_DECREF_IMMORTAL(result);
3387 }
3388 }
3389
3390 Py_LeaveRecursiveCall();
3391
3392 // If it is not implemented, do pointer identity checks as "==" and "!=" and
3393 // otherwise give an error
3394 switch (Py_GT) {
3395 case Py_EQ: {
3396 bool r = operand1 == operand2;
3397 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3398
3399 return result;
3400 }
3401 case Py_NE: {
3402 bool r = operand1 != operand2;
3403 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
3404
3405 return result;
3406 }
3407 default:
3408#if PYTHON_VERSION < 0x300
3409 PyErr_Format(PyExc_TypeError, "unorderable types: unicode() > %s()", type2->tp_name);
3410#elif PYTHON_VERSION < 0x360
3411 PyErr_Format(PyExc_TypeError, "unorderable types: str() > %s()", type2->tp_name);
3412#else
3413 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'str' and '%s'", type2->tp_name);
3414#endif
3415 return NUITKA_BOOL_EXCEPTION;
3416 }
3417#endif
3418}
3419
3420#if PYTHON_VERSION >= 0x300
3421static PyObject *COMPARE_GT_OBJECT_BYTES_BYTES(PyObject *operand1, PyObject *operand2) {
3422 CHECK_OBJECT(operand1);
3423 assert(PyBytes_CheckExact(operand1));
3424 CHECK_OBJECT(operand2);
3425 assert(PyBytes_CheckExact(operand2));
3426
3427 PyBytesObject *a = (PyBytesObject *)operand1;
3428 PyBytesObject *b = (PyBytesObject *)operand2;
3429
3430 // Same object has fast path for all operations.
3431 if (operand1 == operand2) {
3432 bool r = false;
3433
3434 // Convert to target type.
3435 PyObject *result = BOOL_FROM(r);
3436 Py_INCREF_IMMORTAL(result);
3437 return result;
3438 }
3439
3440 Py_ssize_t len_a = Py_SIZE(operand1);
3441 Py_ssize_t len_b = Py_SIZE(operand2);
3442
3443 Py_ssize_t min_len = (len_a < len_b) ? len_a : len_b;
3444 int c;
3445
3446 if (min_len > 0) {
3447 c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
3448
3449 if (c == 0) {
3450 c = memcmp(a->ob_sval, b->ob_sval, min_len);
3451 }
3452 } else {
3453 c = 0;
3454 }
3455
3456 if (c == 0) {
3457 c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
3458 }
3459
3460 c = c > 0;
3461
3462 // Convert to target type.
3463 PyObject *result = BOOL_FROM(c != 0);
3464 Py_INCREF_IMMORTAL(result);
3465 return result;
3466}
3467#endif
3468#if PYTHON_VERSION >= 0x300
3469/* Code referring to "OBJECT" corresponds to any Python object and "BYTES" to Python3 'bytes'. */
3470PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_BYTES(PyObject *operand1, PyObject *operand2) {
3471
3472 if (Py_TYPE(operand1) == &PyBytes_Type) {
3473 return COMPARE_GT_OBJECT_BYTES_BYTES(operand1, operand2);
3474 }
3475
3476#if PYTHON_VERSION < 0x300
3477 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
3478 return NULL;
3479 }
3480#else
3481 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
3482 return NULL;
3483 }
3484#endif
3485
3486 PyTypeObject *type1 = Py_TYPE(operand1);
3487
3488#if PYTHON_VERSION < 0x300
3489 // If the types are equal, we may get away immediately except for instances.
3490 if (type1 == &PyBytes_Type && !0) {
3491
3492 richcmpfunc frich = PyBytes_Type.tp_richcompare;
3493
3494 if (frich != NULL) {
3495 PyObject *result = (*frich)(operand1, operand2, Py_GT);
3496
3497 if (result != Py_NotImplemented) {
3498 Py_LeaveRecursiveCall();
3499
3500 return result;
3501 }
3502
3503 Py_DECREF_IMMORTAL(result);
3504 }
3505
3506 // No rich comparison worked, but maybe compare works.
3507 cmpfunc fcmp = NULL;
3508
3509 if (fcmp != NULL) {
3510 int c = (*fcmp)(operand1, operand2);
3511 c = adjust_tp_compare(c);
3512
3513 Py_LeaveRecursiveCall();
3514
3515 if (c == -2) {
3516 return NULL;
3517 }
3518
3519 switch (Py_GT) {
3520 case Py_LT:
3521 c = c < 0;
3522 break;
3523 case Py_LE:
3524 c = c <= 0;
3525 break;
3526 case Py_EQ:
3527 c = c == 0;
3528 break;
3529 case Py_NE:
3530 c = c != 0;
3531 break;
3532 case Py_GT:
3533 c = c > 0;
3534 break;
3535 case Py_GE:
3536 c = c >= 0;
3537 break;
3538 default:
3539 NUITKA_CANNOT_GET_HERE("wrong op_code");
3540 }
3541
3542 bool r = c != 0;
3543 PyObject *result = BOOL_FROM(r);
3544 Py_INCREF_IMMORTAL(result);
3545 return result;
3546 }
3547 }
3548
3549 // Fast path was not successful or not taken
3550 richcmpfunc f;
3551
3552 if (type1 != &PyBytes_Type && 0) {
3553 f = PyBytes_Type.tp_richcompare;
3554
3555 if (f != NULL) {
3556 PyObject *result = (*f)(operand2, operand1, Py_LT);
3557
3558 if (result != Py_NotImplemented) {
3559 Py_LeaveRecursiveCall();
3560
3561 return result;
3562 }
3563
3564 Py_DECREF_IMMORTAL(result);
3565 }
3566 }
3567
3568 f = TP_RICHCOMPARE(type1);
3569 if (f != NULL) {
3570 PyObject *result = (*f)(operand1, operand2, Py_GT);
3571
3572 if (result != Py_NotImplemented) {
3573 Py_LeaveRecursiveCall();
3574
3575 return result;
3576 }
3577
3578 Py_DECREF_IMMORTAL(result);
3579 }
3580
3581 f = PyBytes_Type.tp_richcompare;
3582 if (f != NULL) {
3583 PyObject *result = (*f)(operand2, operand1, Py_LT);
3584
3585 if (result != Py_NotImplemented) {
3586 Py_LeaveRecursiveCall();
3587
3588 return result;
3589 }
3590
3591 Py_DECREF_IMMORTAL(result);
3592 }
3593
3594 int c;
3595
3596 if (PyInstance_Check(operand1)) {
3597 cmpfunc fcmp = type1->tp_compare;
3598 c = (*fcmp)(operand1, operand2);
3599 } else if (0) {
3600 cmpfunc fcmp = NULL;
3601 c = (*fcmp)(operand1, operand2);
3602 } else {
3603 c = try_3way_compare(operand1, operand2);
3604 }
3605
3606 if (c >= 2) {
3607 if (type1 == &PyBytes_Type) {
3608 Py_uintptr_t aa = (Py_uintptr_t)operand1;
3609 Py_uintptr_t bb = (Py_uintptr_t)operand2;
3610
3611 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3612 } else if (operand1 == Py_None) {
3613 // None is smaller than everything else
3614 c = -1;
3615 } else if (operand2 == Py_None) {
3616 // None is smaller than everything else
3617 c = 1;
3618 } else if (PyNumber_Check(operand1)) {
3619 // different type: compare type names but numbers are smaller than
3620 // others.
3621 if (PyNumber_Check(operand2)) {
3622 // Both numbers, need to make a decision based on types.
3623 Py_uintptr_t aa = (Py_uintptr_t)type1;
3624 Py_uintptr_t bb = (Py_uintptr_t)&PyBytes_Type;
3625
3626 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3627 } else {
3628 c = -1;
3629 }
3630 } else if (PyNumber_Check(operand2)) {
3631 c = 1;
3632 } else {
3633 // Banking on C compile to optimize "strcmp".
3634 int s = strcmp(type1->tp_name, "bytes");
3635
3636 if (s < 0) {
3637 c = -1;
3638 } else if (s > 0) {
3639 c = 1;
3640 } else {
3641 // Same type name need to make a decision based on type address.
3642 Py_uintptr_t aa = (Py_uintptr_t)type1;
3643 Py_uintptr_t bb = (Py_uintptr_t)&PyBytes_Type;
3644
3645 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3646 }
3647 }
3648 }
3649
3650 Py_LeaveRecursiveCall();
3651
3652 if (unlikely(c <= -2)) {
3653 return NULL;
3654 }
3655
3656 switch (Py_GT) {
3657 case Py_LT:
3658 c = c < 0;
3659 break;
3660 case Py_LE:
3661 c = c <= 0;
3662 break;
3663 case Py_EQ:
3664 c = c == 0;
3665 break;
3666 case Py_NE:
3667 c = c != 0;
3668 break;
3669 case Py_GT:
3670 c = c > 0;
3671 break;
3672 case Py_GE:
3673 c = c >= 0;
3674 break;
3675 }
3676
3677 bool r = c != 0;
3678 PyObject *result = BOOL_FROM(r);
3679 Py_INCREF_IMMORTAL(result);
3680 return result;
3681#else
3682 bool checked_reverse_op = false;
3683 richcmpfunc f;
3684
3685 if (type1 != &PyBytes_Type && Nuitka_Type_IsSubtype(&PyBytes_Type, type1)) {
3686 f = PyBytes_Type.tp_richcompare;
3687
3688 if (f != NULL) {
3689 checked_reverse_op = true;
3690
3691 PyObject *result = (*f)(operand2, operand1, Py_LT);
3692
3693 if (result != Py_NotImplemented) {
3694 Py_LeaveRecursiveCall();
3695
3696 return result;
3697 }
3698
3699 Py_DECREF_IMMORTAL(result);
3700 }
3701 }
3702
3703 f = TP_RICHCOMPARE(type1);
3704
3705 if (f != NULL) {
3706 PyObject *result = (*f)(operand1, operand2, Py_GT);
3707
3708 if (result != Py_NotImplemented) {
3709 Py_LeaveRecursiveCall();
3710
3711 return result;
3712 }
3713
3714 Py_DECREF_IMMORTAL(result);
3715 }
3716
3717 if (checked_reverse_op == false) {
3718 f = PyBytes_Type.tp_richcompare;
3719
3720 if (f != NULL) {
3721 PyObject *result = (*f)(operand2, operand1, Py_LT);
3722
3723 if (result != Py_NotImplemented) {
3724 Py_LeaveRecursiveCall();
3725
3726 return result;
3727 }
3728
3729 Py_DECREF_IMMORTAL(result);
3730 }
3731 }
3732
3733 Py_LeaveRecursiveCall();
3734
3735 // If it is not implemented, do pointer identity checks as "==" and "!=" and
3736 // otherwise give an error
3737 switch (Py_GT) {
3738 case Py_EQ: {
3739 bool r = operand1 == operand2;
3740 PyObject *result = BOOL_FROM(r);
3741 Py_INCREF_IMMORTAL(result);
3742 return result;
3743 }
3744 case Py_NE: {
3745 bool r = operand1 != operand2;
3746 PyObject *result = BOOL_FROM(r);
3747 Py_INCREF_IMMORTAL(result);
3748 return result;
3749 }
3750 default:
3751#if PYTHON_VERSION < 0x360
3752 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > bytes()", type1->tp_name);
3753#else
3754 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'bytes'", type1->tp_name);
3755#endif
3756 return NULL;
3757 }
3758#endif
3759}
3760#endif
3761
3762#if PYTHON_VERSION >= 0x300
3763/* Code referring to "BYTES" corresponds to Python3 'bytes' and "OBJECT" to any Python object. */
3764PyObject *RICH_COMPARE_GT_OBJECT_BYTES_OBJECT(PyObject *operand1, PyObject *operand2) {
3765
3766 if (&PyBytes_Type == Py_TYPE(operand2)) {
3767 return COMPARE_GT_OBJECT_BYTES_BYTES(operand1, operand2);
3768 }
3769
3770#if PYTHON_VERSION < 0x300
3771 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
3772 return NULL;
3773 }
3774#else
3775 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
3776 return NULL;
3777 }
3778#endif
3779
3780 PyTypeObject *type2 = Py_TYPE(operand2);
3781
3782#if PYTHON_VERSION < 0x300
3783 // If the types are equal, we may get away immediately except for instances.
3784 if (&PyBytes_Type == type2 && !0) {
3785
3786 richcmpfunc frich = PyBytes_Type.tp_richcompare;
3787
3788 if (frich != NULL) {
3789 PyObject *result = (*frich)(operand1, operand2, Py_GT);
3790
3791 if (result != Py_NotImplemented) {
3792 Py_LeaveRecursiveCall();
3793
3794 return result;
3795 }
3796
3797 Py_DECREF_IMMORTAL(result);
3798 }
3799
3800 // No rich comparison worked, but maybe compare works.
3801 cmpfunc fcmp = NULL;
3802
3803 if (fcmp != NULL) {
3804 int c = (*fcmp)(operand1, operand2);
3805 c = adjust_tp_compare(c);
3806
3807 Py_LeaveRecursiveCall();
3808
3809 if (c == -2) {
3810 return NULL;
3811 }
3812
3813 switch (Py_GT) {
3814 case Py_LT:
3815 c = c < 0;
3816 break;
3817 case Py_LE:
3818 c = c <= 0;
3819 break;
3820 case Py_EQ:
3821 c = c == 0;
3822 break;
3823 case Py_NE:
3824 c = c != 0;
3825 break;
3826 case Py_GT:
3827 c = c > 0;
3828 break;
3829 case Py_GE:
3830 c = c >= 0;
3831 break;
3832 default:
3833 NUITKA_CANNOT_GET_HERE("wrong op_code");
3834 }
3835
3836 bool r = c != 0;
3837 PyObject *result = BOOL_FROM(r);
3838 Py_INCREF_IMMORTAL(result);
3839 return result;
3840 }
3841 }
3842
3843 // Fast path was not successful or not taken
3844 richcmpfunc f;
3845
3846 if (&PyBytes_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyBytes_Type)) {
3847 f = TP_RICHCOMPARE(type2);
3848
3849 if (f != NULL) {
3850 PyObject *result = (*f)(operand2, operand1, Py_LT);
3851
3852 if (result != Py_NotImplemented) {
3853 Py_LeaveRecursiveCall();
3854
3855 return result;
3856 }
3857
3858 Py_DECREF_IMMORTAL(result);
3859 }
3860 }
3861
3862 f = PyBytes_Type.tp_richcompare;
3863 if (f != NULL) {
3864 PyObject *result = (*f)(operand1, operand2, Py_GT);
3865
3866 if (result != Py_NotImplemented) {
3867 Py_LeaveRecursiveCall();
3868
3869 return result;
3870 }
3871
3872 Py_DECREF_IMMORTAL(result);
3873 }
3874
3875 f = TP_RICHCOMPARE(type2);
3876 if (f != NULL) {
3877 PyObject *result = (*f)(operand2, operand1, Py_LT);
3878
3879 if (result != Py_NotImplemented) {
3880 Py_LeaveRecursiveCall();
3881
3882 return result;
3883 }
3884
3885 Py_DECREF_IMMORTAL(result);
3886 }
3887
3888 int c;
3889
3890 if (0) {
3891 cmpfunc fcmp = NULL;
3892 c = (*fcmp)(operand1, operand2);
3893 } else if (PyInstance_Check(operand2)) {
3894 cmpfunc fcmp = type2->tp_compare;
3895 c = (*fcmp)(operand1, operand2);
3896 } else {
3897 c = try_3way_compare(operand1, operand2);
3898 }
3899
3900 if (c >= 2) {
3901 if (&PyBytes_Type == type2) {
3902 Py_uintptr_t aa = (Py_uintptr_t)operand1;
3903 Py_uintptr_t bb = (Py_uintptr_t)operand2;
3904
3905 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3906 } else if (operand1 == Py_None) {
3907 // None is smaller than everything else
3908 c = -1;
3909 } else if (operand2 == Py_None) {
3910 // None is smaller than everything else
3911 c = 1;
3912 } else if (PyNumber_Check(operand1)) {
3913 // different type: compare type names but numbers are smaller than
3914 // others.
3915 if (PyNumber_Check(operand2)) {
3916 // Both numbers, need to make a decision based on types.
3917 Py_uintptr_t aa = (Py_uintptr_t)&PyBytes_Type;
3918 Py_uintptr_t bb = (Py_uintptr_t)type2;
3919
3920 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3921 } else {
3922 c = -1;
3923 }
3924 } else if (PyNumber_Check(operand2)) {
3925 c = 1;
3926 } else {
3927 // Banking on C compile to optimize "strcmp".
3928 int s = strcmp("bytes", type2->tp_name);
3929
3930 if (s < 0) {
3931 c = -1;
3932 } else if (s > 0) {
3933 c = 1;
3934 } else {
3935 // Same type name need to make a decision based on type address.
3936 Py_uintptr_t aa = (Py_uintptr_t)&PyBytes_Type;
3937 Py_uintptr_t bb = (Py_uintptr_t)type2;
3938
3939 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
3940 }
3941 }
3942 }
3943
3944 Py_LeaveRecursiveCall();
3945
3946 if (unlikely(c <= -2)) {
3947 return NULL;
3948 }
3949
3950 switch (Py_GT) {
3951 case Py_LT:
3952 c = c < 0;
3953 break;
3954 case Py_LE:
3955 c = c <= 0;
3956 break;
3957 case Py_EQ:
3958 c = c == 0;
3959 break;
3960 case Py_NE:
3961 c = c != 0;
3962 break;
3963 case Py_GT:
3964 c = c > 0;
3965 break;
3966 case Py_GE:
3967 c = c >= 0;
3968 break;
3969 }
3970
3971 bool r = c != 0;
3972 PyObject *result = BOOL_FROM(r);
3973 Py_INCREF_IMMORTAL(result);
3974 return result;
3975#else
3976 bool checked_reverse_op = false;
3977 richcmpfunc f;
3978
3979 if (&PyBytes_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyBytes_Type)) {
3980 f = TP_RICHCOMPARE(type2);
3981
3982 if (f != NULL) {
3983 checked_reverse_op = true;
3984
3985 PyObject *result = (*f)(operand2, operand1, Py_LT);
3986
3987 if (result != Py_NotImplemented) {
3988 Py_LeaveRecursiveCall();
3989
3990 return result;
3991 }
3992
3993 Py_DECREF_IMMORTAL(result);
3994 }
3995 }
3996
3997 f = PyBytes_Type.tp_richcompare;
3998
3999 if (f != NULL) {
4000 PyObject *result = (*f)(operand1, operand2, Py_GT);
4001
4002 if (result != Py_NotImplemented) {
4003 Py_LeaveRecursiveCall();
4004
4005 return result;
4006 }
4007
4008 Py_DECREF_IMMORTAL(result);
4009 }
4010
4011 if (checked_reverse_op == false) {
4012 f = TP_RICHCOMPARE(type2);
4013
4014 if (f != NULL) {
4015 PyObject *result = (*f)(operand2, operand1, Py_LT);
4016
4017 if (result != Py_NotImplemented) {
4018 Py_LeaveRecursiveCall();
4019
4020 return result;
4021 }
4022
4023 Py_DECREF_IMMORTAL(result);
4024 }
4025 }
4026
4027 Py_LeaveRecursiveCall();
4028
4029 // If it is not implemented, do pointer identity checks as "==" and "!=" and
4030 // otherwise give an error
4031 switch (Py_GT) {
4032 case Py_EQ: {
4033 bool r = operand1 == operand2;
4034 PyObject *result = BOOL_FROM(r);
4035 Py_INCREF_IMMORTAL(result);
4036 return result;
4037 }
4038 case Py_NE: {
4039 bool r = operand1 != operand2;
4040 PyObject *result = BOOL_FROM(r);
4041 Py_INCREF_IMMORTAL(result);
4042 return result;
4043 }
4044 default:
4045#if PYTHON_VERSION < 0x360
4046 PyErr_Format(PyExc_TypeError, "unorderable types: bytes() > %s()", type2->tp_name);
4047#else
4048 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'bytes' and '%s'", type2->tp_name);
4049#endif
4050 return NULL;
4051 }
4052#endif
4053}
4054#endif
4055
4056#if PYTHON_VERSION >= 0x300
4057static bool COMPARE_GT_CBOOL_BYTES_BYTES(PyObject *operand1, PyObject *operand2) {
4058 CHECK_OBJECT(operand1);
4059 assert(PyBytes_CheckExact(operand1));
4060 CHECK_OBJECT(operand2);
4061 assert(PyBytes_CheckExact(operand2));
4062
4063 PyBytesObject *a = (PyBytesObject *)operand1;
4064 PyBytesObject *b = (PyBytesObject *)operand2;
4065
4066 // Same object has fast path for all operations.
4067 if (operand1 == operand2) {
4068 bool r = false;
4069
4070 // Convert to target type.
4071 bool result = r;
4072
4073 return result;
4074 }
4075
4076 Py_ssize_t len_a = Py_SIZE(operand1);
4077 Py_ssize_t len_b = Py_SIZE(operand2);
4078
4079 Py_ssize_t min_len = (len_a < len_b) ? len_a : len_b;
4080 int c;
4081
4082 if (min_len > 0) {
4083 c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval);
4084
4085 if (c == 0) {
4086 c = memcmp(a->ob_sval, b->ob_sval, min_len);
4087 }
4088 } else {
4089 c = 0;
4090 }
4091
4092 if (c == 0) {
4093 c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0;
4094 }
4095
4096 c = c > 0;
4097
4098 // Convert to target type.
4099 bool result = c != 0;
4100
4101 return result;
4102}
4103#endif
4104#if PYTHON_VERSION >= 0x300
4105/* Code referring to "OBJECT" corresponds to any Python object and "BYTES" to Python3 'bytes'. */
4106nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_BYTES(PyObject *operand1, PyObject *operand2) {
4107
4108 if (Py_TYPE(operand1) == &PyBytes_Type) {
4109 return COMPARE_GT_CBOOL_BYTES_BYTES(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4110 }
4111
4112#if PYTHON_VERSION < 0x300
4113 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
4114 return NUITKA_BOOL_EXCEPTION;
4115 }
4116#else
4117 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
4118 return NUITKA_BOOL_EXCEPTION;
4119 }
4120#endif
4121
4122 PyTypeObject *type1 = Py_TYPE(operand1);
4123
4124#if PYTHON_VERSION < 0x300
4125 // If the types are equal, we may get away immediately except for instances.
4126 if (type1 == &PyBytes_Type && !0) {
4127
4128 richcmpfunc frich = PyBytes_Type.tp_richcompare;
4129
4130 if (frich != NULL) {
4131 PyObject *result = (*frich)(operand1, operand2, Py_GT);
4132
4133 if (result != Py_NotImplemented) {
4134 Py_LeaveRecursiveCall();
4135
4136 if (unlikely(result == NULL)) {
4137 return NUITKA_BOOL_EXCEPTION;
4138 }
4139
4140 {
4141 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4142 Py_DECREF(result);
4143 return r;
4144 }
4145 }
4146
4147 Py_DECREF_IMMORTAL(result);
4148 }
4149
4150 // No rich comparison worked, but maybe compare works.
4151 cmpfunc fcmp = NULL;
4152
4153 if (fcmp != NULL) {
4154 int c = (*fcmp)(operand1, operand2);
4155 c = adjust_tp_compare(c);
4156
4157 Py_LeaveRecursiveCall();
4158
4159 if (c == -2) {
4160 return NUITKA_BOOL_EXCEPTION;
4161 }
4162
4163 switch (Py_GT) {
4164 case Py_LT:
4165 c = c < 0;
4166 break;
4167 case Py_LE:
4168 c = c <= 0;
4169 break;
4170 case Py_EQ:
4171 c = c == 0;
4172 break;
4173 case Py_NE:
4174 c = c != 0;
4175 break;
4176 case Py_GT:
4177 c = c > 0;
4178 break;
4179 case Py_GE:
4180 c = c >= 0;
4181 break;
4182 default:
4183 NUITKA_CANNOT_GET_HERE("wrong op_code");
4184 }
4185
4186 bool r = c != 0;
4187 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4188
4189 return result;
4190 }
4191 }
4192
4193 // Fast path was not successful or not taken
4194 richcmpfunc f;
4195
4196 if (type1 != &PyBytes_Type && 0) {
4197 f = PyBytes_Type.tp_richcompare;
4198
4199 if (f != NULL) {
4200 PyObject *result = (*f)(operand2, operand1, Py_LT);
4201
4202 if (result != Py_NotImplemented) {
4203 Py_LeaveRecursiveCall();
4204
4205 if (unlikely(result == NULL)) {
4206 return NUITKA_BOOL_EXCEPTION;
4207 }
4208
4209 {
4210 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4211 Py_DECREF(result);
4212 return r;
4213 }
4214 }
4215
4216 Py_DECREF_IMMORTAL(result);
4217 }
4218 }
4219
4220 f = TP_RICHCOMPARE(type1);
4221 if (f != NULL) {
4222 PyObject *result = (*f)(operand1, operand2, Py_GT);
4223
4224 if (result != Py_NotImplemented) {
4225 Py_LeaveRecursiveCall();
4226
4227 if (unlikely(result == NULL)) {
4228 return NUITKA_BOOL_EXCEPTION;
4229 }
4230
4231 {
4232 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4233 Py_DECREF(result);
4234 return r;
4235 }
4236 }
4237
4238 Py_DECREF_IMMORTAL(result);
4239 }
4240
4241 f = PyBytes_Type.tp_richcompare;
4242 if (f != NULL) {
4243 PyObject *result = (*f)(operand2, operand1, Py_LT);
4244
4245 if (result != Py_NotImplemented) {
4246 Py_LeaveRecursiveCall();
4247
4248 if (unlikely(result == NULL)) {
4249 return NUITKA_BOOL_EXCEPTION;
4250 }
4251
4252 {
4253 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4254 Py_DECREF(result);
4255 return r;
4256 }
4257 }
4258
4259 Py_DECREF_IMMORTAL(result);
4260 }
4261
4262 int c;
4263
4264 if (PyInstance_Check(operand1)) {
4265 cmpfunc fcmp = type1->tp_compare;
4266 c = (*fcmp)(operand1, operand2);
4267 } else if (0) {
4268 cmpfunc fcmp = NULL;
4269 c = (*fcmp)(operand1, operand2);
4270 } else {
4271 c = try_3way_compare(operand1, operand2);
4272 }
4273
4274 if (c >= 2) {
4275 if (type1 == &PyBytes_Type) {
4276 Py_uintptr_t aa = (Py_uintptr_t)operand1;
4277 Py_uintptr_t bb = (Py_uintptr_t)operand2;
4278
4279 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4280 } else if (operand1 == Py_None) {
4281 // None is smaller than everything else
4282 c = -1;
4283 } else if (operand2 == Py_None) {
4284 // None is smaller than everything else
4285 c = 1;
4286 } else if (PyNumber_Check(operand1)) {
4287 // different type: compare type names but numbers are smaller than
4288 // others.
4289 if (PyNumber_Check(operand2)) {
4290 // Both numbers, need to make a decision based on types.
4291 Py_uintptr_t aa = (Py_uintptr_t)type1;
4292 Py_uintptr_t bb = (Py_uintptr_t)&PyBytes_Type;
4293
4294 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4295 } else {
4296 c = -1;
4297 }
4298 } else if (PyNumber_Check(operand2)) {
4299 c = 1;
4300 } else {
4301 // Banking on C compile to optimize "strcmp".
4302 int s = strcmp(type1->tp_name, "bytes");
4303
4304 if (s < 0) {
4305 c = -1;
4306 } else if (s > 0) {
4307 c = 1;
4308 } else {
4309 // Same type name need to make a decision based on type address.
4310 Py_uintptr_t aa = (Py_uintptr_t)type1;
4311 Py_uintptr_t bb = (Py_uintptr_t)&PyBytes_Type;
4312
4313 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4314 }
4315 }
4316 }
4317
4318 Py_LeaveRecursiveCall();
4319
4320 if (unlikely(c <= -2)) {
4321 return NUITKA_BOOL_EXCEPTION;
4322 }
4323
4324 switch (Py_GT) {
4325 case Py_LT:
4326 c = c < 0;
4327 break;
4328 case Py_LE:
4329 c = c <= 0;
4330 break;
4331 case Py_EQ:
4332 c = c == 0;
4333 break;
4334 case Py_NE:
4335 c = c != 0;
4336 break;
4337 case Py_GT:
4338 c = c > 0;
4339 break;
4340 case Py_GE:
4341 c = c >= 0;
4342 break;
4343 }
4344
4345 bool r = c != 0;
4346 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4347
4348 return result;
4349#else
4350 bool checked_reverse_op = false;
4351 richcmpfunc f;
4352
4353 if (type1 != &PyBytes_Type && Nuitka_Type_IsSubtype(&PyBytes_Type, type1)) {
4354 f = PyBytes_Type.tp_richcompare;
4355
4356 if (f != NULL) {
4357 checked_reverse_op = true;
4358
4359 PyObject *result = (*f)(operand2, operand1, Py_LT);
4360
4361 if (result != Py_NotImplemented) {
4362 Py_LeaveRecursiveCall();
4363
4364 if (unlikely(result == NULL)) {
4365 return NUITKA_BOOL_EXCEPTION;
4366 }
4367
4368 {
4369 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4370 Py_DECREF(result);
4371 return r;
4372 }
4373 }
4374
4375 Py_DECREF_IMMORTAL(result);
4376 }
4377 }
4378
4379 f = TP_RICHCOMPARE(type1);
4380
4381 if (f != NULL) {
4382 PyObject *result = (*f)(operand1, operand2, Py_GT);
4383
4384 if (result != Py_NotImplemented) {
4385 Py_LeaveRecursiveCall();
4386
4387 if (unlikely(result == NULL)) {
4388 return NUITKA_BOOL_EXCEPTION;
4389 }
4390
4391 {
4392 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4393 Py_DECREF(result);
4394 return r;
4395 }
4396 }
4397
4398 Py_DECREF_IMMORTAL(result);
4399 }
4400
4401 if (checked_reverse_op == false) {
4402 f = PyBytes_Type.tp_richcompare;
4403
4404 if (f != NULL) {
4405 PyObject *result = (*f)(operand2, operand1, Py_LT);
4406
4407 if (result != Py_NotImplemented) {
4408 Py_LeaveRecursiveCall();
4409
4410 if (unlikely(result == NULL)) {
4411 return NUITKA_BOOL_EXCEPTION;
4412 }
4413
4414 {
4415 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4416 Py_DECREF(result);
4417 return r;
4418 }
4419 }
4420
4421 Py_DECREF_IMMORTAL(result);
4422 }
4423 }
4424
4425 Py_LeaveRecursiveCall();
4426
4427 // If it is not implemented, do pointer identity checks as "==" and "!=" and
4428 // otherwise give an error
4429 switch (Py_GT) {
4430 case Py_EQ: {
4431 bool r = operand1 == operand2;
4432 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4433
4434 return result;
4435 }
4436 case Py_NE: {
4437 bool r = operand1 != operand2;
4438 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4439
4440 return result;
4441 }
4442 default:
4443#if PYTHON_VERSION < 0x360
4444 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > bytes()", type1->tp_name);
4445#else
4446 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'bytes'", type1->tp_name);
4447#endif
4448 return NUITKA_BOOL_EXCEPTION;
4449 }
4450#endif
4451}
4452#endif
4453
4454#if PYTHON_VERSION >= 0x300
4455/* Code referring to "BYTES" corresponds to Python3 'bytes' and "OBJECT" to any Python object. */
4456nuitka_bool RICH_COMPARE_GT_NBOOL_BYTES_OBJECT(PyObject *operand1, PyObject *operand2) {
4457
4458 if (&PyBytes_Type == Py_TYPE(operand2)) {
4459 return COMPARE_GT_CBOOL_BYTES_BYTES(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4460 }
4461
4462#if PYTHON_VERSION < 0x300
4463 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
4464 return NUITKA_BOOL_EXCEPTION;
4465 }
4466#else
4467 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
4468 return NUITKA_BOOL_EXCEPTION;
4469 }
4470#endif
4471
4472 PyTypeObject *type2 = Py_TYPE(operand2);
4473
4474#if PYTHON_VERSION < 0x300
4475 // If the types are equal, we may get away immediately except for instances.
4476 if (&PyBytes_Type == type2 && !0) {
4477
4478 richcmpfunc frich = PyBytes_Type.tp_richcompare;
4479
4480 if (frich != NULL) {
4481 PyObject *result = (*frich)(operand1, operand2, Py_GT);
4482
4483 if (result != Py_NotImplemented) {
4484 Py_LeaveRecursiveCall();
4485
4486 if (unlikely(result == NULL)) {
4487 return NUITKA_BOOL_EXCEPTION;
4488 }
4489
4490 {
4491 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4492 Py_DECREF(result);
4493 return r;
4494 }
4495 }
4496
4497 Py_DECREF_IMMORTAL(result);
4498 }
4499
4500 // No rich comparison worked, but maybe compare works.
4501 cmpfunc fcmp = NULL;
4502
4503 if (fcmp != NULL) {
4504 int c = (*fcmp)(operand1, operand2);
4505 c = adjust_tp_compare(c);
4506
4507 Py_LeaveRecursiveCall();
4508
4509 if (c == -2) {
4510 return NUITKA_BOOL_EXCEPTION;
4511 }
4512
4513 switch (Py_GT) {
4514 case Py_LT:
4515 c = c < 0;
4516 break;
4517 case Py_LE:
4518 c = c <= 0;
4519 break;
4520 case Py_EQ:
4521 c = c == 0;
4522 break;
4523 case Py_NE:
4524 c = c != 0;
4525 break;
4526 case Py_GT:
4527 c = c > 0;
4528 break;
4529 case Py_GE:
4530 c = c >= 0;
4531 break;
4532 default:
4533 NUITKA_CANNOT_GET_HERE("wrong op_code");
4534 }
4535
4536 bool r = c != 0;
4537 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4538
4539 return result;
4540 }
4541 }
4542
4543 // Fast path was not successful or not taken
4544 richcmpfunc f;
4545
4546 if (&PyBytes_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyBytes_Type)) {
4547 f = TP_RICHCOMPARE(type2);
4548
4549 if (f != NULL) {
4550 PyObject *result = (*f)(operand2, operand1, Py_LT);
4551
4552 if (result != Py_NotImplemented) {
4553 Py_LeaveRecursiveCall();
4554
4555 if (unlikely(result == NULL)) {
4556 return NUITKA_BOOL_EXCEPTION;
4557 }
4558
4559 {
4560 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4561 Py_DECREF(result);
4562 return r;
4563 }
4564 }
4565
4566 Py_DECREF_IMMORTAL(result);
4567 }
4568 }
4569
4570 f = PyBytes_Type.tp_richcompare;
4571 if (f != NULL) {
4572 PyObject *result = (*f)(operand1, operand2, Py_GT);
4573
4574 if (result != Py_NotImplemented) {
4575 Py_LeaveRecursiveCall();
4576
4577 if (unlikely(result == NULL)) {
4578 return NUITKA_BOOL_EXCEPTION;
4579 }
4580
4581 {
4582 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4583 Py_DECREF(result);
4584 return r;
4585 }
4586 }
4587
4588 Py_DECREF_IMMORTAL(result);
4589 }
4590
4591 f = TP_RICHCOMPARE(type2);
4592 if (f != NULL) {
4593 PyObject *result = (*f)(operand2, operand1, Py_LT);
4594
4595 if (result != Py_NotImplemented) {
4596 Py_LeaveRecursiveCall();
4597
4598 if (unlikely(result == NULL)) {
4599 return NUITKA_BOOL_EXCEPTION;
4600 }
4601
4602 {
4603 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4604 Py_DECREF(result);
4605 return r;
4606 }
4607 }
4608
4609 Py_DECREF_IMMORTAL(result);
4610 }
4611
4612 int c;
4613
4614 if (0) {
4615 cmpfunc fcmp = NULL;
4616 c = (*fcmp)(operand1, operand2);
4617 } else if (PyInstance_Check(operand2)) {
4618 cmpfunc fcmp = type2->tp_compare;
4619 c = (*fcmp)(operand1, operand2);
4620 } else {
4621 c = try_3way_compare(operand1, operand2);
4622 }
4623
4624 if (c >= 2) {
4625 if (&PyBytes_Type == type2) {
4626 Py_uintptr_t aa = (Py_uintptr_t)operand1;
4627 Py_uintptr_t bb = (Py_uintptr_t)operand2;
4628
4629 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4630 } else if (operand1 == Py_None) {
4631 // None is smaller than everything else
4632 c = -1;
4633 } else if (operand2 == Py_None) {
4634 // None is smaller than everything else
4635 c = 1;
4636 } else if (PyNumber_Check(operand1)) {
4637 // different type: compare type names but numbers are smaller than
4638 // others.
4639 if (PyNumber_Check(operand2)) {
4640 // Both numbers, need to make a decision based on types.
4641 Py_uintptr_t aa = (Py_uintptr_t)&PyBytes_Type;
4642 Py_uintptr_t bb = (Py_uintptr_t)type2;
4643
4644 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4645 } else {
4646 c = -1;
4647 }
4648 } else if (PyNumber_Check(operand2)) {
4649 c = 1;
4650 } else {
4651 // Banking on C compile to optimize "strcmp".
4652 int s = strcmp("bytes", type2->tp_name);
4653
4654 if (s < 0) {
4655 c = -1;
4656 } else if (s > 0) {
4657 c = 1;
4658 } else {
4659 // Same type name need to make a decision based on type address.
4660 Py_uintptr_t aa = (Py_uintptr_t)&PyBytes_Type;
4661 Py_uintptr_t bb = (Py_uintptr_t)type2;
4662
4663 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4664 }
4665 }
4666 }
4667
4668 Py_LeaveRecursiveCall();
4669
4670 if (unlikely(c <= -2)) {
4671 return NUITKA_BOOL_EXCEPTION;
4672 }
4673
4674 switch (Py_GT) {
4675 case Py_LT:
4676 c = c < 0;
4677 break;
4678 case Py_LE:
4679 c = c <= 0;
4680 break;
4681 case Py_EQ:
4682 c = c == 0;
4683 break;
4684 case Py_NE:
4685 c = c != 0;
4686 break;
4687 case Py_GT:
4688 c = c > 0;
4689 break;
4690 case Py_GE:
4691 c = c >= 0;
4692 break;
4693 }
4694
4695 bool r = c != 0;
4696 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4697
4698 return result;
4699#else
4700 bool checked_reverse_op = false;
4701 richcmpfunc f;
4702
4703 if (&PyBytes_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyBytes_Type)) {
4704 f = TP_RICHCOMPARE(type2);
4705
4706 if (f != NULL) {
4707 checked_reverse_op = true;
4708
4709 PyObject *result = (*f)(operand2, operand1, Py_LT);
4710
4711 if (result != Py_NotImplemented) {
4712 Py_LeaveRecursiveCall();
4713
4714 if (unlikely(result == NULL)) {
4715 return NUITKA_BOOL_EXCEPTION;
4716 }
4717
4718 {
4719 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4720 Py_DECREF(result);
4721 return r;
4722 }
4723 }
4724
4725 Py_DECREF_IMMORTAL(result);
4726 }
4727 }
4728
4729 f = PyBytes_Type.tp_richcompare;
4730
4731 if (f != NULL) {
4732 PyObject *result = (*f)(operand1, operand2, Py_GT);
4733
4734 if (result != Py_NotImplemented) {
4735 Py_LeaveRecursiveCall();
4736
4737 if (unlikely(result == NULL)) {
4738 return NUITKA_BOOL_EXCEPTION;
4739 }
4740
4741 {
4742 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4743 Py_DECREF(result);
4744 return r;
4745 }
4746 }
4747
4748 Py_DECREF_IMMORTAL(result);
4749 }
4750
4751 if (checked_reverse_op == false) {
4752 f = TP_RICHCOMPARE(type2);
4753
4754 if (f != NULL) {
4755 PyObject *result = (*f)(operand2, operand1, Py_LT);
4756
4757 if (result != Py_NotImplemented) {
4758 Py_LeaveRecursiveCall();
4759
4760 if (unlikely(result == NULL)) {
4761 return NUITKA_BOOL_EXCEPTION;
4762 }
4763
4764 {
4765 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4766 Py_DECREF(result);
4767 return r;
4768 }
4769 }
4770
4771 Py_DECREF_IMMORTAL(result);
4772 }
4773 }
4774
4775 Py_LeaveRecursiveCall();
4776
4777 // If it is not implemented, do pointer identity checks as "==" and "!=" and
4778 // otherwise give an error
4779 switch (Py_GT) {
4780 case Py_EQ: {
4781 bool r = operand1 == operand2;
4782 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4783
4784 return result;
4785 }
4786 case Py_NE: {
4787 bool r = operand1 != operand2;
4788 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
4789
4790 return result;
4791 }
4792 default:
4793#if PYTHON_VERSION < 0x360
4794 PyErr_Format(PyExc_TypeError, "unorderable types: bytes() > %s()", type2->tp_name);
4795#else
4796 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'bytes' and '%s'", type2->tp_name);
4797#endif
4798 return NUITKA_BOOL_EXCEPTION;
4799 }
4800#endif
4801}
4802#endif
4803
4804#if PYTHON_VERSION < 0x300
4805/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
4806PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
4807
4808 if (Py_TYPE(operand1) == &PyInt_Type) {
4809 return COMPARE_GT_OBJECT_INT_INT(operand1, operand2);
4810 }
4811
4812#if PYTHON_VERSION < 0x300
4813 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
4814 return NULL;
4815 }
4816#else
4817 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
4818 return NULL;
4819 }
4820#endif
4821
4822 PyTypeObject *type1 = Py_TYPE(operand1);
4823
4824#if PYTHON_VERSION < 0x300
4825 // If the types are equal, we may get away immediately except for instances.
4826 if (type1 == &PyInt_Type && !0) {
4827
4828 richcmpfunc frich = NULL;
4829
4830 if (frich != NULL) {
4831 PyObject *result = (*frich)(operand1, operand2, Py_GT);
4832
4833 if (result != Py_NotImplemented) {
4834 Py_LeaveRecursiveCall();
4835
4836 return result;
4837 }
4838
4839 Py_DECREF_IMMORTAL(result);
4840 }
4841
4842 // No rich comparison worked, but maybe compare works.
4843 cmpfunc fcmp = PyInt_Type.tp_compare;
4844
4845 if (fcmp != NULL) {
4846 int c = (*fcmp)(operand1, operand2);
4847 c = adjust_tp_compare(c);
4848
4849 Py_LeaveRecursiveCall();
4850
4851 if (c == -2) {
4852 return NULL;
4853 }
4854
4855 switch (Py_GT) {
4856 case Py_LT:
4857 c = c < 0;
4858 break;
4859 case Py_LE:
4860 c = c <= 0;
4861 break;
4862 case Py_EQ:
4863 c = c == 0;
4864 break;
4865 case Py_NE:
4866 c = c != 0;
4867 break;
4868 case Py_GT:
4869 c = c > 0;
4870 break;
4871 case Py_GE:
4872 c = c >= 0;
4873 break;
4874 default:
4875 NUITKA_CANNOT_GET_HERE("wrong op_code");
4876 }
4877
4878 bool r = c != 0;
4879 PyObject *result = BOOL_FROM(r);
4880 Py_INCREF_IMMORTAL(result);
4881 return result;
4882 }
4883 }
4884
4885 // Fast path was not successful or not taken
4886 richcmpfunc f;
4887
4888 if (type1 != &PyInt_Type && 0) {
4889 f = NULL;
4890
4891 if (f != NULL) {
4892 PyObject *result = (*f)(operand2, operand1, Py_LT);
4893
4894 if (result != Py_NotImplemented) {
4895 Py_LeaveRecursiveCall();
4896
4897 return result;
4898 }
4899
4900 Py_DECREF_IMMORTAL(result);
4901 }
4902 }
4903
4904 f = TP_RICHCOMPARE(type1);
4905 if (f != NULL) {
4906 PyObject *result = (*f)(operand1, operand2, Py_GT);
4907
4908 if (result != Py_NotImplemented) {
4909 Py_LeaveRecursiveCall();
4910
4911 return result;
4912 }
4913
4914 Py_DECREF_IMMORTAL(result);
4915 }
4916
4917 f = NULL;
4918 if (f != NULL) {
4919 PyObject *result = (*f)(operand2, operand1, Py_LT);
4920
4921 if (result != Py_NotImplemented) {
4922 Py_LeaveRecursiveCall();
4923
4924 return result;
4925 }
4926
4927 Py_DECREF_IMMORTAL(result);
4928 }
4929
4930 int c;
4931
4932 if (PyInstance_Check(operand1)) {
4933 cmpfunc fcmp = type1->tp_compare;
4934 c = (*fcmp)(operand1, operand2);
4935 } else if (0) {
4936 cmpfunc fcmp = PyInt_Type.tp_compare;
4937 c = (*fcmp)(operand1, operand2);
4938 } else {
4939 c = try_3way_compare(operand1, operand2);
4940 }
4941
4942 if (c >= 2) {
4943 if (type1 == &PyInt_Type) {
4944 Py_uintptr_t aa = (Py_uintptr_t)operand1;
4945 Py_uintptr_t bb = (Py_uintptr_t)operand2;
4946
4947 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4948 } else if (operand1 == Py_None) {
4949 // None is smaller than everything else
4950 c = -1;
4951 } else if (operand2 == Py_None) {
4952 // None is smaller than everything else
4953 c = 1;
4954 } else if (PyNumber_Check(operand1)) {
4955 // different type: compare type names but numbers are smaller than
4956 // others.
4957 if (PyNumber_Check(operand2)) {
4958 // Both numbers, need to make a decision based on types.
4959 Py_uintptr_t aa = (Py_uintptr_t)type1;
4960 Py_uintptr_t bb = (Py_uintptr_t)&PyInt_Type;
4961
4962 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4963 } else {
4964 c = -1;
4965 }
4966 } else if (PyNumber_Check(operand2)) {
4967 c = 1;
4968 } else {
4969 // Banking on C compile to optimize "strcmp".
4970 int s = strcmp(type1->tp_name, "int");
4971
4972 if (s < 0) {
4973 c = -1;
4974 } else if (s > 0) {
4975 c = 1;
4976 } else {
4977 // Same type name need to make a decision based on type address.
4978 Py_uintptr_t aa = (Py_uintptr_t)type1;
4979 Py_uintptr_t bb = (Py_uintptr_t)&PyInt_Type;
4980
4981 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
4982 }
4983 }
4984 }
4985
4986 Py_LeaveRecursiveCall();
4987
4988 if (unlikely(c <= -2)) {
4989 return NULL;
4990 }
4991
4992 switch (Py_GT) {
4993 case Py_LT:
4994 c = c < 0;
4995 break;
4996 case Py_LE:
4997 c = c <= 0;
4998 break;
4999 case Py_EQ:
5000 c = c == 0;
5001 break;
5002 case Py_NE:
5003 c = c != 0;
5004 break;
5005 case Py_GT:
5006 c = c > 0;
5007 break;
5008 case Py_GE:
5009 c = c >= 0;
5010 break;
5011 }
5012
5013 bool r = c != 0;
5014 PyObject *result = BOOL_FROM(r);
5015 Py_INCREF_IMMORTAL(result);
5016 return result;
5017#else
5018 bool checked_reverse_op = false;
5019 richcmpfunc f;
5020
5021 if (type1 != &PyInt_Type && Nuitka_Type_IsSubtype(&PyInt_Type, type1)) {
5022 f = NULL;
5023
5024 if (f != NULL) {
5025 checked_reverse_op = true;
5026
5027 PyObject *result = (*f)(operand2, operand1, Py_LT);
5028
5029 if (result != Py_NotImplemented) {
5030 Py_LeaveRecursiveCall();
5031
5032 return result;
5033 }
5034
5035 Py_DECREF_IMMORTAL(result);
5036 }
5037 }
5038
5039 f = TP_RICHCOMPARE(type1);
5040
5041 if (f != NULL) {
5042 PyObject *result = (*f)(operand1, operand2, Py_GT);
5043
5044 if (result != Py_NotImplemented) {
5045 Py_LeaveRecursiveCall();
5046
5047 return result;
5048 }
5049
5050 Py_DECREF_IMMORTAL(result);
5051 }
5052
5053 if (checked_reverse_op == false) {
5054 f = NULL;
5055
5056 if (f != NULL) {
5057 PyObject *result = (*f)(operand2, operand1, Py_LT);
5058
5059 if (result != Py_NotImplemented) {
5060 Py_LeaveRecursiveCall();
5061
5062 return result;
5063 }
5064
5065 Py_DECREF_IMMORTAL(result);
5066 }
5067 }
5068
5069 Py_LeaveRecursiveCall();
5070
5071 // If it is not implemented, do pointer identity checks as "==" and "!=" and
5072 // otherwise give an error
5073 switch (Py_GT) {
5074 case Py_EQ: {
5075 bool r = operand1 == operand2;
5076 PyObject *result = BOOL_FROM(r);
5077 Py_INCREF_IMMORTAL(result);
5078 return result;
5079 }
5080 case Py_NE: {
5081 bool r = operand1 != operand2;
5082 PyObject *result = BOOL_FROM(r);
5083 Py_INCREF_IMMORTAL(result);
5084 return result;
5085 }
5086 default:
5087#if PYTHON_VERSION < 0x360
5088 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > int()", type1->tp_name);
5089#else
5090 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'int'", type1->tp_name);
5091#endif
5092 return NULL;
5093 }
5094#endif
5095}
5096#endif
5097
5098#if PYTHON_VERSION < 0x300
5099/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
5100PyObject *RICH_COMPARE_GT_OBJECT_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
5101
5102 if (&PyInt_Type == Py_TYPE(operand2)) {
5103 return COMPARE_GT_OBJECT_INT_INT(operand1, operand2);
5104 }
5105
5106#if PYTHON_VERSION < 0x300
5107 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
5108 return NULL;
5109 }
5110#else
5111 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
5112 return NULL;
5113 }
5114#endif
5115
5116 PyTypeObject *type2 = Py_TYPE(operand2);
5117
5118#if PYTHON_VERSION < 0x300
5119 // If the types are equal, we may get away immediately except for instances.
5120 if (&PyInt_Type == type2 && !0) {
5121
5122 richcmpfunc frich = NULL;
5123
5124 if (frich != NULL) {
5125 PyObject *result = (*frich)(operand1, operand2, Py_GT);
5126
5127 if (result != Py_NotImplemented) {
5128 Py_LeaveRecursiveCall();
5129
5130 return result;
5131 }
5132
5133 Py_DECREF_IMMORTAL(result);
5134 }
5135
5136 // No rich comparison worked, but maybe compare works.
5137 cmpfunc fcmp = PyInt_Type.tp_compare;
5138
5139 if (fcmp != NULL) {
5140 int c = (*fcmp)(operand1, operand2);
5141 c = adjust_tp_compare(c);
5142
5143 Py_LeaveRecursiveCall();
5144
5145 if (c == -2) {
5146 return NULL;
5147 }
5148
5149 switch (Py_GT) {
5150 case Py_LT:
5151 c = c < 0;
5152 break;
5153 case Py_LE:
5154 c = c <= 0;
5155 break;
5156 case Py_EQ:
5157 c = c == 0;
5158 break;
5159 case Py_NE:
5160 c = c != 0;
5161 break;
5162 case Py_GT:
5163 c = c > 0;
5164 break;
5165 case Py_GE:
5166 c = c >= 0;
5167 break;
5168 default:
5169 NUITKA_CANNOT_GET_HERE("wrong op_code");
5170 }
5171
5172 bool r = c != 0;
5173 PyObject *result = BOOL_FROM(r);
5174 Py_INCREF_IMMORTAL(result);
5175 return result;
5176 }
5177 }
5178
5179 // Fast path was not successful or not taken
5180 richcmpfunc f;
5181
5182 if (&PyInt_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
5183 f = TP_RICHCOMPARE(type2);
5184
5185 if (f != NULL) {
5186 PyObject *result = (*f)(operand2, operand1, Py_LT);
5187
5188 if (result != Py_NotImplemented) {
5189 Py_LeaveRecursiveCall();
5190
5191 return result;
5192 }
5193
5194 Py_DECREF_IMMORTAL(result);
5195 }
5196 }
5197
5198 f = NULL;
5199 if (f != NULL) {
5200 PyObject *result = (*f)(operand1, operand2, Py_GT);
5201
5202 if (result != Py_NotImplemented) {
5203 Py_LeaveRecursiveCall();
5204
5205 return result;
5206 }
5207
5208 Py_DECREF_IMMORTAL(result);
5209 }
5210
5211 f = TP_RICHCOMPARE(type2);
5212 if (f != NULL) {
5213 PyObject *result = (*f)(operand2, operand1, Py_LT);
5214
5215 if (result != Py_NotImplemented) {
5216 Py_LeaveRecursiveCall();
5217
5218 return result;
5219 }
5220
5221 Py_DECREF_IMMORTAL(result);
5222 }
5223
5224 int c;
5225
5226 if (0) {
5227 cmpfunc fcmp = PyInt_Type.tp_compare;
5228 c = (*fcmp)(operand1, operand2);
5229 } else if (PyInstance_Check(operand2)) {
5230 cmpfunc fcmp = type2->tp_compare;
5231 c = (*fcmp)(operand1, operand2);
5232 } else {
5233 c = try_3way_compare(operand1, operand2);
5234 }
5235
5236 if (c >= 2) {
5237 if (&PyInt_Type == type2) {
5238 Py_uintptr_t aa = (Py_uintptr_t)operand1;
5239 Py_uintptr_t bb = (Py_uintptr_t)operand2;
5240
5241 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5242 } else if (operand1 == Py_None) {
5243 // None is smaller than everything else
5244 c = -1;
5245 } else if (operand2 == Py_None) {
5246 // None is smaller than everything else
5247 c = 1;
5248 } else if (PyNumber_Check(operand1)) {
5249 // different type: compare type names but numbers are smaller than
5250 // others.
5251 if (PyNumber_Check(operand2)) {
5252 // Both numbers, need to make a decision based on types.
5253 Py_uintptr_t aa = (Py_uintptr_t)&PyInt_Type;
5254 Py_uintptr_t bb = (Py_uintptr_t)type2;
5255
5256 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5257 } else {
5258 c = -1;
5259 }
5260 } else if (PyNumber_Check(operand2)) {
5261 c = 1;
5262 } else {
5263 // Banking on C compile to optimize "strcmp".
5264 int s = strcmp("int", type2->tp_name);
5265
5266 if (s < 0) {
5267 c = -1;
5268 } else if (s > 0) {
5269 c = 1;
5270 } else {
5271 // Same type name need to make a decision based on type address.
5272 Py_uintptr_t aa = (Py_uintptr_t)&PyInt_Type;
5273 Py_uintptr_t bb = (Py_uintptr_t)type2;
5274
5275 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5276 }
5277 }
5278 }
5279
5280 Py_LeaveRecursiveCall();
5281
5282 if (unlikely(c <= -2)) {
5283 return NULL;
5284 }
5285
5286 switch (Py_GT) {
5287 case Py_LT:
5288 c = c < 0;
5289 break;
5290 case Py_LE:
5291 c = c <= 0;
5292 break;
5293 case Py_EQ:
5294 c = c == 0;
5295 break;
5296 case Py_NE:
5297 c = c != 0;
5298 break;
5299 case Py_GT:
5300 c = c > 0;
5301 break;
5302 case Py_GE:
5303 c = c >= 0;
5304 break;
5305 }
5306
5307 bool r = c != 0;
5308 PyObject *result = BOOL_FROM(r);
5309 Py_INCREF_IMMORTAL(result);
5310 return result;
5311#else
5312 bool checked_reverse_op = false;
5313 richcmpfunc f;
5314
5315 if (&PyInt_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
5316 f = TP_RICHCOMPARE(type2);
5317
5318 if (f != NULL) {
5319 checked_reverse_op = true;
5320
5321 PyObject *result = (*f)(operand2, operand1, Py_LT);
5322
5323 if (result != Py_NotImplemented) {
5324 Py_LeaveRecursiveCall();
5325
5326 return result;
5327 }
5328
5329 Py_DECREF_IMMORTAL(result);
5330 }
5331 }
5332
5333 f = NULL;
5334
5335 if (f != NULL) {
5336 PyObject *result = (*f)(operand1, operand2, Py_GT);
5337
5338 if (result != Py_NotImplemented) {
5339 Py_LeaveRecursiveCall();
5340
5341 return result;
5342 }
5343
5344 Py_DECREF_IMMORTAL(result);
5345 }
5346
5347 if (checked_reverse_op == false) {
5348 f = TP_RICHCOMPARE(type2);
5349
5350 if (f != NULL) {
5351 PyObject *result = (*f)(operand2, operand1, Py_LT);
5352
5353 if (result != Py_NotImplemented) {
5354 Py_LeaveRecursiveCall();
5355
5356 return result;
5357 }
5358
5359 Py_DECREF_IMMORTAL(result);
5360 }
5361 }
5362
5363 Py_LeaveRecursiveCall();
5364
5365 // If it is not implemented, do pointer identity checks as "==" and "!=" and
5366 // otherwise give an error
5367 switch (Py_GT) {
5368 case Py_EQ: {
5369 bool r = operand1 == operand2;
5370 PyObject *result = BOOL_FROM(r);
5371 Py_INCREF_IMMORTAL(result);
5372 return result;
5373 }
5374 case Py_NE: {
5375 bool r = operand1 != operand2;
5376 PyObject *result = BOOL_FROM(r);
5377 Py_INCREF_IMMORTAL(result);
5378 return result;
5379 }
5380 default:
5381#if PYTHON_VERSION < 0x360
5382 PyErr_Format(PyExc_TypeError, "unorderable types: int() > %s()", type2->tp_name);
5383#else
5384 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'int' and '%s'", type2->tp_name);
5385#endif
5386 return NULL;
5387 }
5388#endif
5389}
5390#endif
5391
5392#if PYTHON_VERSION < 0x300
5393/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
5394nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_INT(PyObject *operand1, PyObject *operand2) {
5395
5396 if (Py_TYPE(operand1) == &PyInt_Type) {
5397 return COMPARE_GT_CBOOL_INT_INT(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5398 }
5399
5400#if PYTHON_VERSION < 0x300
5401 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
5402 return NUITKA_BOOL_EXCEPTION;
5403 }
5404#else
5405 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
5406 return NUITKA_BOOL_EXCEPTION;
5407 }
5408#endif
5409
5410 PyTypeObject *type1 = Py_TYPE(operand1);
5411
5412#if PYTHON_VERSION < 0x300
5413 // If the types are equal, we may get away immediately except for instances.
5414 if (type1 == &PyInt_Type && !0) {
5415
5416 richcmpfunc frich = NULL;
5417
5418 if (frich != NULL) {
5419 PyObject *result = (*frich)(operand1, operand2, Py_GT);
5420
5421 if (result != Py_NotImplemented) {
5422 Py_LeaveRecursiveCall();
5423
5424 if (unlikely(result == NULL)) {
5425 return NUITKA_BOOL_EXCEPTION;
5426 }
5427
5428 {
5429 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5430 Py_DECREF(result);
5431 return r;
5432 }
5433 }
5434
5435 Py_DECREF_IMMORTAL(result);
5436 }
5437
5438 // No rich comparison worked, but maybe compare works.
5439 cmpfunc fcmp = PyInt_Type.tp_compare;
5440
5441 if (fcmp != NULL) {
5442 int c = (*fcmp)(operand1, operand2);
5443 c = adjust_tp_compare(c);
5444
5445 Py_LeaveRecursiveCall();
5446
5447 if (c == -2) {
5448 return NUITKA_BOOL_EXCEPTION;
5449 }
5450
5451 switch (Py_GT) {
5452 case Py_LT:
5453 c = c < 0;
5454 break;
5455 case Py_LE:
5456 c = c <= 0;
5457 break;
5458 case Py_EQ:
5459 c = c == 0;
5460 break;
5461 case Py_NE:
5462 c = c != 0;
5463 break;
5464 case Py_GT:
5465 c = c > 0;
5466 break;
5467 case Py_GE:
5468 c = c >= 0;
5469 break;
5470 default:
5471 NUITKA_CANNOT_GET_HERE("wrong op_code");
5472 }
5473
5474 bool r = c != 0;
5475 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5476
5477 return result;
5478 }
5479 }
5480
5481 // Fast path was not successful or not taken
5482 richcmpfunc f;
5483
5484 if (type1 != &PyInt_Type && 0) {
5485 f = NULL;
5486
5487 if (f != NULL) {
5488 PyObject *result = (*f)(operand2, operand1, Py_LT);
5489
5490 if (result != Py_NotImplemented) {
5491 Py_LeaveRecursiveCall();
5492
5493 if (unlikely(result == NULL)) {
5494 return NUITKA_BOOL_EXCEPTION;
5495 }
5496
5497 {
5498 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5499 Py_DECREF(result);
5500 return r;
5501 }
5502 }
5503
5504 Py_DECREF_IMMORTAL(result);
5505 }
5506 }
5507
5508 f = TP_RICHCOMPARE(type1);
5509 if (f != NULL) {
5510 PyObject *result = (*f)(operand1, operand2, Py_GT);
5511
5512 if (result != Py_NotImplemented) {
5513 Py_LeaveRecursiveCall();
5514
5515 if (unlikely(result == NULL)) {
5516 return NUITKA_BOOL_EXCEPTION;
5517 }
5518
5519 {
5520 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5521 Py_DECREF(result);
5522 return r;
5523 }
5524 }
5525
5526 Py_DECREF_IMMORTAL(result);
5527 }
5528
5529 f = NULL;
5530 if (f != NULL) {
5531 PyObject *result = (*f)(operand2, operand1, Py_LT);
5532
5533 if (result != Py_NotImplemented) {
5534 Py_LeaveRecursiveCall();
5535
5536 if (unlikely(result == NULL)) {
5537 return NUITKA_BOOL_EXCEPTION;
5538 }
5539
5540 {
5541 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5542 Py_DECREF(result);
5543 return r;
5544 }
5545 }
5546
5547 Py_DECREF_IMMORTAL(result);
5548 }
5549
5550 int c;
5551
5552 if (PyInstance_Check(operand1)) {
5553 cmpfunc fcmp = type1->tp_compare;
5554 c = (*fcmp)(operand1, operand2);
5555 } else if (0) {
5556 cmpfunc fcmp = PyInt_Type.tp_compare;
5557 c = (*fcmp)(operand1, operand2);
5558 } else {
5559 c = try_3way_compare(operand1, operand2);
5560 }
5561
5562 if (c >= 2) {
5563 if (type1 == &PyInt_Type) {
5564 Py_uintptr_t aa = (Py_uintptr_t)operand1;
5565 Py_uintptr_t bb = (Py_uintptr_t)operand2;
5566
5567 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5568 } else if (operand1 == Py_None) {
5569 // None is smaller than everything else
5570 c = -1;
5571 } else if (operand2 == Py_None) {
5572 // None is smaller than everything else
5573 c = 1;
5574 } else if (PyNumber_Check(operand1)) {
5575 // different type: compare type names but numbers are smaller than
5576 // others.
5577 if (PyNumber_Check(operand2)) {
5578 // Both numbers, need to make a decision based on types.
5579 Py_uintptr_t aa = (Py_uintptr_t)type1;
5580 Py_uintptr_t bb = (Py_uintptr_t)&PyInt_Type;
5581
5582 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5583 } else {
5584 c = -1;
5585 }
5586 } else if (PyNumber_Check(operand2)) {
5587 c = 1;
5588 } else {
5589 // Banking on C compile to optimize "strcmp".
5590 int s = strcmp(type1->tp_name, "int");
5591
5592 if (s < 0) {
5593 c = -1;
5594 } else if (s > 0) {
5595 c = 1;
5596 } else {
5597 // Same type name need to make a decision based on type address.
5598 Py_uintptr_t aa = (Py_uintptr_t)type1;
5599 Py_uintptr_t bb = (Py_uintptr_t)&PyInt_Type;
5600
5601 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5602 }
5603 }
5604 }
5605
5606 Py_LeaveRecursiveCall();
5607
5608 if (unlikely(c <= -2)) {
5609 return NUITKA_BOOL_EXCEPTION;
5610 }
5611
5612 switch (Py_GT) {
5613 case Py_LT:
5614 c = c < 0;
5615 break;
5616 case Py_LE:
5617 c = c <= 0;
5618 break;
5619 case Py_EQ:
5620 c = c == 0;
5621 break;
5622 case Py_NE:
5623 c = c != 0;
5624 break;
5625 case Py_GT:
5626 c = c > 0;
5627 break;
5628 case Py_GE:
5629 c = c >= 0;
5630 break;
5631 }
5632
5633 bool r = c != 0;
5634 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5635
5636 return result;
5637#else
5638 bool checked_reverse_op = false;
5639 richcmpfunc f;
5640
5641 if (type1 != &PyInt_Type && Nuitka_Type_IsSubtype(&PyInt_Type, type1)) {
5642 f = NULL;
5643
5644 if (f != NULL) {
5645 checked_reverse_op = true;
5646
5647 PyObject *result = (*f)(operand2, operand1, Py_LT);
5648
5649 if (result != Py_NotImplemented) {
5650 Py_LeaveRecursiveCall();
5651
5652 if (unlikely(result == NULL)) {
5653 return NUITKA_BOOL_EXCEPTION;
5654 }
5655
5656 {
5657 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5658 Py_DECREF(result);
5659 return r;
5660 }
5661 }
5662
5663 Py_DECREF_IMMORTAL(result);
5664 }
5665 }
5666
5667 f = TP_RICHCOMPARE(type1);
5668
5669 if (f != NULL) {
5670 PyObject *result = (*f)(operand1, operand2, Py_GT);
5671
5672 if (result != Py_NotImplemented) {
5673 Py_LeaveRecursiveCall();
5674
5675 if (unlikely(result == NULL)) {
5676 return NUITKA_BOOL_EXCEPTION;
5677 }
5678
5679 {
5680 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5681 Py_DECREF(result);
5682 return r;
5683 }
5684 }
5685
5686 Py_DECREF_IMMORTAL(result);
5687 }
5688
5689 if (checked_reverse_op == false) {
5690 f = NULL;
5691
5692 if (f != NULL) {
5693 PyObject *result = (*f)(operand2, operand1, Py_LT);
5694
5695 if (result != Py_NotImplemented) {
5696 Py_LeaveRecursiveCall();
5697
5698 if (unlikely(result == NULL)) {
5699 return NUITKA_BOOL_EXCEPTION;
5700 }
5701
5702 {
5703 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5704 Py_DECREF(result);
5705 return r;
5706 }
5707 }
5708
5709 Py_DECREF_IMMORTAL(result);
5710 }
5711 }
5712
5713 Py_LeaveRecursiveCall();
5714
5715 // If it is not implemented, do pointer identity checks as "==" and "!=" and
5716 // otherwise give an error
5717 switch (Py_GT) {
5718 case Py_EQ: {
5719 bool r = operand1 == operand2;
5720 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5721
5722 return result;
5723 }
5724 case Py_NE: {
5725 bool r = operand1 != operand2;
5726 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5727
5728 return result;
5729 }
5730 default:
5731#if PYTHON_VERSION < 0x360
5732 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > int()", type1->tp_name);
5733#else
5734 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'int'", type1->tp_name);
5735#endif
5736 return NUITKA_BOOL_EXCEPTION;
5737 }
5738#endif
5739}
5740#endif
5741
5742#if PYTHON_VERSION < 0x300
5743/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
5744nuitka_bool RICH_COMPARE_GT_NBOOL_INT_OBJECT(PyObject *operand1, PyObject *operand2) {
5745
5746 if (&PyInt_Type == Py_TYPE(operand2)) {
5747 return COMPARE_GT_CBOOL_INT_INT(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5748 }
5749
5750#if PYTHON_VERSION < 0x300
5751 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
5752 return NUITKA_BOOL_EXCEPTION;
5753 }
5754#else
5755 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
5756 return NUITKA_BOOL_EXCEPTION;
5757 }
5758#endif
5759
5760 PyTypeObject *type2 = Py_TYPE(operand2);
5761
5762#if PYTHON_VERSION < 0x300
5763 // If the types are equal, we may get away immediately except for instances.
5764 if (&PyInt_Type == type2 && !0) {
5765
5766 richcmpfunc frich = NULL;
5767
5768 if (frich != NULL) {
5769 PyObject *result = (*frich)(operand1, operand2, Py_GT);
5770
5771 if (result != Py_NotImplemented) {
5772 Py_LeaveRecursiveCall();
5773
5774 if (unlikely(result == NULL)) {
5775 return NUITKA_BOOL_EXCEPTION;
5776 }
5777
5778 {
5779 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5780 Py_DECREF(result);
5781 return r;
5782 }
5783 }
5784
5785 Py_DECREF_IMMORTAL(result);
5786 }
5787
5788 // No rich comparison worked, but maybe compare works.
5789 cmpfunc fcmp = PyInt_Type.tp_compare;
5790
5791 if (fcmp != NULL) {
5792 int c = (*fcmp)(operand1, operand2);
5793 c = adjust_tp_compare(c);
5794
5795 Py_LeaveRecursiveCall();
5796
5797 if (c == -2) {
5798 return NUITKA_BOOL_EXCEPTION;
5799 }
5800
5801 switch (Py_GT) {
5802 case Py_LT:
5803 c = c < 0;
5804 break;
5805 case Py_LE:
5806 c = c <= 0;
5807 break;
5808 case Py_EQ:
5809 c = c == 0;
5810 break;
5811 case Py_NE:
5812 c = c != 0;
5813 break;
5814 case Py_GT:
5815 c = c > 0;
5816 break;
5817 case Py_GE:
5818 c = c >= 0;
5819 break;
5820 default:
5821 NUITKA_CANNOT_GET_HERE("wrong op_code");
5822 }
5823
5824 bool r = c != 0;
5825 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5826
5827 return result;
5828 }
5829 }
5830
5831 // Fast path was not successful or not taken
5832 richcmpfunc f;
5833
5834 if (&PyInt_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
5835 f = TP_RICHCOMPARE(type2);
5836
5837 if (f != NULL) {
5838 PyObject *result = (*f)(operand2, operand1, Py_LT);
5839
5840 if (result != Py_NotImplemented) {
5841 Py_LeaveRecursiveCall();
5842
5843 if (unlikely(result == NULL)) {
5844 return NUITKA_BOOL_EXCEPTION;
5845 }
5846
5847 {
5848 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5849 Py_DECREF(result);
5850 return r;
5851 }
5852 }
5853
5854 Py_DECREF_IMMORTAL(result);
5855 }
5856 }
5857
5858 f = NULL;
5859 if (f != NULL) {
5860 PyObject *result = (*f)(operand1, operand2, Py_GT);
5861
5862 if (result != Py_NotImplemented) {
5863 Py_LeaveRecursiveCall();
5864
5865 if (unlikely(result == NULL)) {
5866 return NUITKA_BOOL_EXCEPTION;
5867 }
5868
5869 {
5870 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5871 Py_DECREF(result);
5872 return r;
5873 }
5874 }
5875
5876 Py_DECREF_IMMORTAL(result);
5877 }
5878
5879 f = TP_RICHCOMPARE(type2);
5880 if (f != NULL) {
5881 PyObject *result = (*f)(operand2, operand1, Py_LT);
5882
5883 if (result != Py_NotImplemented) {
5884 Py_LeaveRecursiveCall();
5885
5886 if (unlikely(result == NULL)) {
5887 return NUITKA_BOOL_EXCEPTION;
5888 }
5889
5890 {
5891 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5892 Py_DECREF(result);
5893 return r;
5894 }
5895 }
5896
5897 Py_DECREF_IMMORTAL(result);
5898 }
5899
5900 int c;
5901
5902 if (0) {
5903 cmpfunc fcmp = PyInt_Type.tp_compare;
5904 c = (*fcmp)(operand1, operand2);
5905 } else if (PyInstance_Check(operand2)) {
5906 cmpfunc fcmp = type2->tp_compare;
5907 c = (*fcmp)(operand1, operand2);
5908 } else {
5909 c = try_3way_compare(operand1, operand2);
5910 }
5911
5912 if (c >= 2) {
5913 if (&PyInt_Type == type2) {
5914 Py_uintptr_t aa = (Py_uintptr_t)operand1;
5915 Py_uintptr_t bb = (Py_uintptr_t)operand2;
5916
5917 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5918 } else if (operand1 == Py_None) {
5919 // None is smaller than everything else
5920 c = -1;
5921 } else if (operand2 == Py_None) {
5922 // None is smaller than everything else
5923 c = 1;
5924 } else if (PyNumber_Check(operand1)) {
5925 // different type: compare type names but numbers are smaller than
5926 // others.
5927 if (PyNumber_Check(operand2)) {
5928 // Both numbers, need to make a decision based on types.
5929 Py_uintptr_t aa = (Py_uintptr_t)&PyInt_Type;
5930 Py_uintptr_t bb = (Py_uintptr_t)type2;
5931
5932 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5933 } else {
5934 c = -1;
5935 }
5936 } else if (PyNumber_Check(operand2)) {
5937 c = 1;
5938 } else {
5939 // Banking on C compile to optimize "strcmp".
5940 int s = strcmp("int", type2->tp_name);
5941
5942 if (s < 0) {
5943 c = -1;
5944 } else if (s > 0) {
5945 c = 1;
5946 } else {
5947 // Same type name need to make a decision based on type address.
5948 Py_uintptr_t aa = (Py_uintptr_t)&PyInt_Type;
5949 Py_uintptr_t bb = (Py_uintptr_t)type2;
5950
5951 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
5952 }
5953 }
5954 }
5955
5956 Py_LeaveRecursiveCall();
5957
5958 if (unlikely(c <= -2)) {
5959 return NUITKA_BOOL_EXCEPTION;
5960 }
5961
5962 switch (Py_GT) {
5963 case Py_LT:
5964 c = c < 0;
5965 break;
5966 case Py_LE:
5967 c = c <= 0;
5968 break;
5969 case Py_EQ:
5970 c = c == 0;
5971 break;
5972 case Py_NE:
5973 c = c != 0;
5974 break;
5975 case Py_GT:
5976 c = c > 0;
5977 break;
5978 case Py_GE:
5979 c = c >= 0;
5980 break;
5981 }
5982
5983 bool r = c != 0;
5984 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
5985
5986 return result;
5987#else
5988 bool checked_reverse_op = false;
5989 richcmpfunc f;
5990
5991 if (&PyInt_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
5992 f = TP_RICHCOMPARE(type2);
5993
5994 if (f != NULL) {
5995 checked_reverse_op = true;
5996
5997 PyObject *result = (*f)(operand2, operand1, Py_LT);
5998
5999 if (result != Py_NotImplemented) {
6000 Py_LeaveRecursiveCall();
6001
6002 if (unlikely(result == NULL)) {
6003 return NUITKA_BOOL_EXCEPTION;
6004 }
6005
6006 {
6007 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6008 Py_DECREF(result);
6009 return r;
6010 }
6011 }
6012
6013 Py_DECREF_IMMORTAL(result);
6014 }
6015 }
6016
6017 f = NULL;
6018
6019 if (f != NULL) {
6020 PyObject *result = (*f)(operand1, operand2, Py_GT);
6021
6022 if (result != Py_NotImplemented) {
6023 Py_LeaveRecursiveCall();
6024
6025 if (unlikely(result == NULL)) {
6026 return NUITKA_BOOL_EXCEPTION;
6027 }
6028
6029 {
6030 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6031 Py_DECREF(result);
6032 return r;
6033 }
6034 }
6035
6036 Py_DECREF_IMMORTAL(result);
6037 }
6038
6039 if (checked_reverse_op == false) {
6040 f = TP_RICHCOMPARE(type2);
6041
6042 if (f != NULL) {
6043 PyObject *result = (*f)(operand2, operand1, Py_LT);
6044
6045 if (result != Py_NotImplemented) {
6046 Py_LeaveRecursiveCall();
6047
6048 if (unlikely(result == NULL)) {
6049 return NUITKA_BOOL_EXCEPTION;
6050 }
6051
6052 {
6053 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6054 Py_DECREF(result);
6055 return r;
6056 }
6057 }
6058
6059 Py_DECREF_IMMORTAL(result);
6060 }
6061 }
6062
6063 Py_LeaveRecursiveCall();
6064
6065 // If it is not implemented, do pointer identity checks as "==" and "!=" and
6066 // otherwise give an error
6067 switch (Py_GT) {
6068 case Py_EQ: {
6069 bool r = operand1 == operand2;
6070 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6071
6072 return result;
6073 }
6074 case Py_NE: {
6075 bool r = operand1 != operand2;
6076 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6077
6078 return result;
6079 }
6080 default:
6081#if PYTHON_VERSION < 0x360
6082 PyErr_Format(PyExc_TypeError, "unorderable types: int() > %s()", type2->tp_name);
6083#else
6084 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'int' and '%s'", type2->tp_name);
6085#endif
6086 return NUITKA_BOOL_EXCEPTION;
6087 }
6088#endif
6089}
6090#endif
6091
6092static PyObject *COMPARE_GT_OBJECT_LONG_LONG(PyObject *operand1, PyObject *operand2) {
6093 CHECK_OBJECT(operand1);
6094 assert(PyLong_CheckExact(operand1));
6095 CHECK_OBJECT(operand2);
6096 assert(PyLong_CheckExact(operand2));
6097
6098 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
6099
6100 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
6101
6102 bool r;
6103
6104 if (operand1_long_object == operand2_long_object) {
6105 r = false;
6106 } else if (Nuitka_LongGetSignedDigitSize(operand1_long_object) !=
6107 Nuitka_LongGetSignedDigitSize(operand2_long_object)) {
6108 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) - Nuitka_LongGetSignedDigitSize(operand2_long_object) >
6109 0;
6110 } else {
6111 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
6112 r = false;
6113 while (--i >= 0) {
6114 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] !=
6115 Nuitka_LongGetDigitPointer(operand2_long_object)[i]) {
6116 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] >
6117 Nuitka_LongGetDigitPointer(operand2_long_object)[i];
6118 if (Nuitka_LongIsNegative(operand1_long_object)) {
6119 r = !r;
6120 }
6121 break;
6122 }
6123 }
6124 }
6125
6126 // Convert to target type.
6127 PyObject *result = BOOL_FROM(r);
6128 Py_INCREF_IMMORTAL(result);
6129 return result;
6130}
6131/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
6132PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
6133
6134 if (Py_TYPE(operand1) == &PyLong_Type) {
6135 return COMPARE_GT_OBJECT_LONG_LONG(operand1, operand2);
6136 }
6137
6138#if PYTHON_VERSION < 0x300
6139 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
6140 return NULL;
6141 }
6142#else
6143 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
6144 return NULL;
6145 }
6146#endif
6147
6148 PyTypeObject *type1 = Py_TYPE(operand1);
6149
6150#if PYTHON_VERSION < 0x300
6151 // If the types are equal, we may get away immediately except for instances.
6152 if (type1 == &PyLong_Type && !0) {
6153
6154 richcmpfunc frich = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6155
6156 if (frich != NULL) {
6157 PyObject *result = (*frich)(operand1, operand2, Py_GT);
6158
6159 if (result != Py_NotImplemented) {
6160 Py_LeaveRecursiveCall();
6161
6162 return result;
6163 }
6164
6165 Py_DECREF_IMMORTAL(result);
6166 }
6167
6168 // No rich comparison worked, but maybe compare works.
6169 cmpfunc fcmp = PyLong_Type.tp_compare;
6170
6171 if (fcmp != NULL) {
6172 int c = (*fcmp)(operand1, operand2);
6173 c = adjust_tp_compare(c);
6174
6175 Py_LeaveRecursiveCall();
6176
6177 if (c == -2) {
6178 return NULL;
6179 }
6180
6181 switch (Py_GT) {
6182 case Py_LT:
6183 c = c < 0;
6184 break;
6185 case Py_LE:
6186 c = c <= 0;
6187 break;
6188 case Py_EQ:
6189 c = c == 0;
6190 break;
6191 case Py_NE:
6192 c = c != 0;
6193 break;
6194 case Py_GT:
6195 c = c > 0;
6196 break;
6197 case Py_GE:
6198 c = c >= 0;
6199 break;
6200 default:
6201 NUITKA_CANNOT_GET_HERE("wrong op_code");
6202 }
6203
6204 bool r = c != 0;
6205 PyObject *result = BOOL_FROM(r);
6206 Py_INCREF_IMMORTAL(result);
6207 return result;
6208 }
6209 }
6210
6211 // Fast path was not successful or not taken
6212 richcmpfunc f;
6213
6214 if (type1 != &PyLong_Type && 0) {
6215 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6216
6217 if (f != NULL) {
6218 PyObject *result = (*f)(operand2, operand1, Py_LT);
6219
6220 if (result != Py_NotImplemented) {
6221 Py_LeaveRecursiveCall();
6222
6223 return result;
6224 }
6225
6226 Py_DECREF_IMMORTAL(result);
6227 }
6228 }
6229
6230 f = TP_RICHCOMPARE(type1);
6231 if (f != NULL) {
6232 PyObject *result = (*f)(operand1, operand2, Py_GT);
6233
6234 if (result != Py_NotImplemented) {
6235 Py_LeaveRecursiveCall();
6236
6237 return result;
6238 }
6239
6240 Py_DECREF_IMMORTAL(result);
6241 }
6242
6243 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6244 if (f != NULL) {
6245 PyObject *result = (*f)(operand2, operand1, Py_LT);
6246
6247 if (result != Py_NotImplemented) {
6248 Py_LeaveRecursiveCall();
6249
6250 return result;
6251 }
6252
6253 Py_DECREF_IMMORTAL(result);
6254 }
6255
6256 int c;
6257
6258 if (PyInstance_Check(operand1)) {
6259 cmpfunc fcmp = type1->tp_compare;
6260 c = (*fcmp)(operand1, operand2);
6261 } else if (0) {
6262 cmpfunc fcmp = PyLong_Type.tp_compare;
6263 c = (*fcmp)(operand1, operand2);
6264 } else {
6265 c = try_3way_compare(operand1, operand2);
6266 }
6267
6268 if (c >= 2) {
6269 if (type1 == &PyLong_Type) {
6270 Py_uintptr_t aa = (Py_uintptr_t)operand1;
6271 Py_uintptr_t bb = (Py_uintptr_t)operand2;
6272
6273 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6274 } else if (operand1 == Py_None) {
6275 // None is smaller than everything else
6276 c = -1;
6277 } else if (operand2 == Py_None) {
6278 // None is smaller than everything else
6279 c = 1;
6280 } else if (PyNumber_Check(operand1)) {
6281 // different type: compare type names but numbers are smaller than
6282 // others.
6283 if (PyNumber_Check(operand2)) {
6284 // Both numbers, need to make a decision based on types.
6285 Py_uintptr_t aa = (Py_uintptr_t)type1;
6286 Py_uintptr_t bb = (Py_uintptr_t)&PyLong_Type;
6287
6288 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6289 } else {
6290 c = -1;
6291 }
6292 } else if (PyNumber_Check(operand2)) {
6293 c = 1;
6294 } else {
6295 // Banking on C compile to optimize "strcmp".
6296 int s = strcmp(type1->tp_name, (PYTHON_VERSION < 0x300 ? "long" : "int"));
6297
6298 if (s < 0) {
6299 c = -1;
6300 } else if (s > 0) {
6301 c = 1;
6302 } else {
6303 // Same type name need to make a decision based on type address.
6304 Py_uintptr_t aa = (Py_uintptr_t)type1;
6305 Py_uintptr_t bb = (Py_uintptr_t)&PyLong_Type;
6306
6307 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6308 }
6309 }
6310 }
6311
6312 Py_LeaveRecursiveCall();
6313
6314 if (unlikely(c <= -2)) {
6315 return NULL;
6316 }
6317
6318 switch (Py_GT) {
6319 case Py_LT:
6320 c = c < 0;
6321 break;
6322 case Py_LE:
6323 c = c <= 0;
6324 break;
6325 case Py_EQ:
6326 c = c == 0;
6327 break;
6328 case Py_NE:
6329 c = c != 0;
6330 break;
6331 case Py_GT:
6332 c = c > 0;
6333 break;
6334 case Py_GE:
6335 c = c >= 0;
6336 break;
6337 }
6338
6339 bool r = c != 0;
6340 PyObject *result = BOOL_FROM(r);
6341 Py_INCREF_IMMORTAL(result);
6342 return result;
6343#else
6344 bool checked_reverse_op = false;
6345 richcmpfunc f;
6346
6347 if (type1 != &PyLong_Type && Nuitka_Type_IsSubtype(&PyLong_Type, type1)) {
6348 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6349
6350 if (f != NULL) {
6351 checked_reverse_op = true;
6352
6353 PyObject *result = (*f)(operand2, operand1, Py_LT);
6354
6355 if (result != Py_NotImplemented) {
6356 Py_LeaveRecursiveCall();
6357
6358 return result;
6359 }
6360
6361 Py_DECREF_IMMORTAL(result);
6362 }
6363 }
6364
6365 f = TP_RICHCOMPARE(type1);
6366
6367 if (f != NULL) {
6368 PyObject *result = (*f)(operand1, operand2, Py_GT);
6369
6370 if (result != Py_NotImplemented) {
6371 Py_LeaveRecursiveCall();
6372
6373 return result;
6374 }
6375
6376 Py_DECREF_IMMORTAL(result);
6377 }
6378
6379 if (checked_reverse_op == false) {
6380 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6381
6382 if (f != NULL) {
6383 PyObject *result = (*f)(operand2, operand1, Py_LT);
6384
6385 if (result != Py_NotImplemented) {
6386 Py_LeaveRecursiveCall();
6387
6388 return result;
6389 }
6390
6391 Py_DECREF_IMMORTAL(result);
6392 }
6393 }
6394
6395 Py_LeaveRecursiveCall();
6396
6397 // If it is not implemented, do pointer identity checks as "==" and "!=" and
6398 // otherwise give an error
6399 switch (Py_GT) {
6400 case Py_EQ: {
6401 bool r = operand1 == operand2;
6402 PyObject *result = BOOL_FROM(r);
6403 Py_INCREF_IMMORTAL(result);
6404 return result;
6405 }
6406 case Py_NE: {
6407 bool r = operand1 != operand2;
6408 PyObject *result = BOOL_FROM(r);
6409 Py_INCREF_IMMORTAL(result);
6410 return result;
6411 }
6412 default:
6413#if PYTHON_VERSION < 0x300
6414 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > long()", type1->tp_name);
6415#elif PYTHON_VERSION < 0x360
6416 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > int()", type1->tp_name);
6417#else
6418 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'int'", type1->tp_name);
6419#endif
6420 return NULL;
6421 }
6422#endif
6423}
6424
6425/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
6426PyObject *RICH_COMPARE_GT_OBJECT_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
6427
6428 if (&PyLong_Type == Py_TYPE(operand2)) {
6429 return COMPARE_GT_OBJECT_LONG_LONG(operand1, operand2);
6430 }
6431
6432#if PYTHON_VERSION < 0x300
6433 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
6434 return NULL;
6435 }
6436#else
6437 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
6438 return NULL;
6439 }
6440#endif
6441
6442 PyTypeObject *type2 = Py_TYPE(operand2);
6443
6444#if PYTHON_VERSION < 0x300
6445 // If the types are equal, we may get away immediately except for instances.
6446 if (&PyLong_Type == type2 && !0) {
6447
6448 richcmpfunc frich = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6449
6450 if (frich != NULL) {
6451 PyObject *result = (*frich)(operand1, operand2, Py_GT);
6452
6453 if (result != Py_NotImplemented) {
6454 Py_LeaveRecursiveCall();
6455
6456 return result;
6457 }
6458
6459 Py_DECREF_IMMORTAL(result);
6460 }
6461
6462 // No rich comparison worked, but maybe compare works.
6463 cmpfunc fcmp = PyLong_Type.tp_compare;
6464
6465 if (fcmp != NULL) {
6466 int c = (*fcmp)(operand1, operand2);
6467 c = adjust_tp_compare(c);
6468
6469 Py_LeaveRecursiveCall();
6470
6471 if (c == -2) {
6472 return NULL;
6473 }
6474
6475 switch (Py_GT) {
6476 case Py_LT:
6477 c = c < 0;
6478 break;
6479 case Py_LE:
6480 c = c <= 0;
6481 break;
6482 case Py_EQ:
6483 c = c == 0;
6484 break;
6485 case Py_NE:
6486 c = c != 0;
6487 break;
6488 case Py_GT:
6489 c = c > 0;
6490 break;
6491 case Py_GE:
6492 c = c >= 0;
6493 break;
6494 default:
6495 NUITKA_CANNOT_GET_HERE("wrong op_code");
6496 }
6497
6498 bool r = c != 0;
6499 PyObject *result = BOOL_FROM(r);
6500 Py_INCREF_IMMORTAL(result);
6501 return result;
6502 }
6503 }
6504
6505 // Fast path was not successful or not taken
6506 richcmpfunc f;
6507
6508 if (&PyLong_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
6509 f = TP_RICHCOMPARE(type2);
6510
6511 if (f != NULL) {
6512 PyObject *result = (*f)(operand2, operand1, Py_LT);
6513
6514 if (result != Py_NotImplemented) {
6515 Py_LeaveRecursiveCall();
6516
6517 return result;
6518 }
6519
6520 Py_DECREF_IMMORTAL(result);
6521 }
6522 }
6523
6524 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6525 if (f != NULL) {
6526 PyObject *result = (*f)(operand1, operand2, Py_GT);
6527
6528 if (result != Py_NotImplemented) {
6529 Py_LeaveRecursiveCall();
6530
6531 return result;
6532 }
6533
6534 Py_DECREF_IMMORTAL(result);
6535 }
6536
6537 f = TP_RICHCOMPARE(type2);
6538 if (f != NULL) {
6539 PyObject *result = (*f)(operand2, operand1, Py_LT);
6540
6541 if (result != Py_NotImplemented) {
6542 Py_LeaveRecursiveCall();
6543
6544 return result;
6545 }
6546
6547 Py_DECREF_IMMORTAL(result);
6548 }
6549
6550 int c;
6551
6552 if (0) {
6553 cmpfunc fcmp = PyLong_Type.tp_compare;
6554 c = (*fcmp)(operand1, operand2);
6555 } else if (PyInstance_Check(operand2)) {
6556 cmpfunc fcmp = type2->tp_compare;
6557 c = (*fcmp)(operand1, operand2);
6558 } else {
6559 c = try_3way_compare(operand1, operand2);
6560 }
6561
6562 if (c >= 2) {
6563 if (&PyLong_Type == type2) {
6564 Py_uintptr_t aa = (Py_uintptr_t)operand1;
6565 Py_uintptr_t bb = (Py_uintptr_t)operand2;
6566
6567 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6568 } else if (operand1 == Py_None) {
6569 // None is smaller than everything else
6570 c = -1;
6571 } else if (operand2 == Py_None) {
6572 // None is smaller than everything else
6573 c = 1;
6574 } else if (PyNumber_Check(operand1)) {
6575 // different type: compare type names but numbers are smaller than
6576 // others.
6577 if (PyNumber_Check(operand2)) {
6578 // Both numbers, need to make a decision based on types.
6579 Py_uintptr_t aa = (Py_uintptr_t)&PyLong_Type;
6580 Py_uintptr_t bb = (Py_uintptr_t)type2;
6581
6582 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6583 } else {
6584 c = -1;
6585 }
6586 } else if (PyNumber_Check(operand2)) {
6587 c = 1;
6588 } else {
6589 // Banking on C compile to optimize "strcmp".
6590 int s = strcmp((PYTHON_VERSION < 0x300 ? "long" : "int"), type2->tp_name);
6591
6592 if (s < 0) {
6593 c = -1;
6594 } else if (s > 0) {
6595 c = 1;
6596 } else {
6597 // Same type name need to make a decision based on type address.
6598 Py_uintptr_t aa = (Py_uintptr_t)&PyLong_Type;
6599 Py_uintptr_t bb = (Py_uintptr_t)type2;
6600
6601 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6602 }
6603 }
6604 }
6605
6606 Py_LeaveRecursiveCall();
6607
6608 if (unlikely(c <= -2)) {
6609 return NULL;
6610 }
6611
6612 switch (Py_GT) {
6613 case Py_LT:
6614 c = c < 0;
6615 break;
6616 case Py_LE:
6617 c = c <= 0;
6618 break;
6619 case Py_EQ:
6620 c = c == 0;
6621 break;
6622 case Py_NE:
6623 c = c != 0;
6624 break;
6625 case Py_GT:
6626 c = c > 0;
6627 break;
6628 case Py_GE:
6629 c = c >= 0;
6630 break;
6631 }
6632
6633 bool r = c != 0;
6634 PyObject *result = BOOL_FROM(r);
6635 Py_INCREF_IMMORTAL(result);
6636 return result;
6637#else
6638 bool checked_reverse_op = false;
6639 richcmpfunc f;
6640
6641 if (&PyLong_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
6642 f = TP_RICHCOMPARE(type2);
6643
6644 if (f != NULL) {
6645 checked_reverse_op = true;
6646
6647 PyObject *result = (*f)(operand2, operand1, Py_LT);
6648
6649 if (result != Py_NotImplemented) {
6650 Py_LeaveRecursiveCall();
6651
6652 return result;
6653 }
6654
6655 Py_DECREF_IMMORTAL(result);
6656 }
6657 }
6658
6659 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6660
6661 if (f != NULL) {
6662 PyObject *result = (*f)(operand1, operand2, Py_GT);
6663
6664 if (result != Py_NotImplemented) {
6665 Py_LeaveRecursiveCall();
6666
6667 return result;
6668 }
6669
6670 Py_DECREF_IMMORTAL(result);
6671 }
6672
6673 if (checked_reverse_op == false) {
6674 f = TP_RICHCOMPARE(type2);
6675
6676 if (f != NULL) {
6677 PyObject *result = (*f)(operand2, operand1, Py_LT);
6678
6679 if (result != Py_NotImplemented) {
6680 Py_LeaveRecursiveCall();
6681
6682 return result;
6683 }
6684
6685 Py_DECREF_IMMORTAL(result);
6686 }
6687 }
6688
6689 Py_LeaveRecursiveCall();
6690
6691 // If it is not implemented, do pointer identity checks as "==" and "!=" and
6692 // otherwise give an error
6693 switch (Py_GT) {
6694 case Py_EQ: {
6695 bool r = operand1 == operand2;
6696 PyObject *result = BOOL_FROM(r);
6697 Py_INCREF_IMMORTAL(result);
6698 return result;
6699 }
6700 case Py_NE: {
6701 bool r = operand1 != operand2;
6702 PyObject *result = BOOL_FROM(r);
6703 Py_INCREF_IMMORTAL(result);
6704 return result;
6705 }
6706 default:
6707#if PYTHON_VERSION < 0x300
6708 PyErr_Format(PyExc_TypeError, "unorderable types: long() > %s()", type2->tp_name);
6709#elif PYTHON_VERSION < 0x360
6710 PyErr_Format(PyExc_TypeError, "unorderable types: int() > %s()", type2->tp_name);
6711#else
6712 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'int' and '%s'", type2->tp_name);
6713#endif
6714 return NULL;
6715 }
6716#endif
6717}
6718
6719static bool COMPARE_GT_CBOOL_LONG_LONG(PyObject *operand1, PyObject *operand2) {
6720 CHECK_OBJECT(operand1);
6721 assert(PyLong_CheckExact(operand1));
6722 CHECK_OBJECT(operand2);
6723 assert(PyLong_CheckExact(operand2));
6724
6725 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
6726
6727 PyLongObject *operand2_long_object = (PyLongObject *)operand2;
6728
6729 bool r;
6730
6731 if (operand1_long_object == operand2_long_object) {
6732 r = false;
6733 } else if (Nuitka_LongGetSignedDigitSize(operand1_long_object) !=
6734 Nuitka_LongGetSignedDigitSize(operand2_long_object)) {
6735 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) - Nuitka_LongGetSignedDigitSize(operand2_long_object) >
6736 0;
6737 } else {
6738 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
6739 r = false;
6740 while (--i >= 0) {
6741 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] !=
6742 Nuitka_LongGetDigitPointer(operand2_long_object)[i]) {
6743 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] >
6744 Nuitka_LongGetDigitPointer(operand2_long_object)[i];
6745 if (Nuitka_LongIsNegative(operand1_long_object)) {
6746 r = !r;
6747 }
6748 break;
6749 }
6750 }
6751 }
6752
6753 // Convert to target type.
6754 bool result = r;
6755
6756 return result;
6757}
6758/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
6759nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_LONG(PyObject *operand1, PyObject *operand2) {
6760
6761 if (Py_TYPE(operand1) == &PyLong_Type) {
6762 return COMPARE_GT_CBOOL_LONG_LONG(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6763 }
6764
6765#if PYTHON_VERSION < 0x300
6766 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
6767 return NUITKA_BOOL_EXCEPTION;
6768 }
6769#else
6770 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
6771 return NUITKA_BOOL_EXCEPTION;
6772 }
6773#endif
6774
6775 PyTypeObject *type1 = Py_TYPE(operand1);
6776
6777#if PYTHON_VERSION < 0x300
6778 // If the types are equal, we may get away immediately except for instances.
6779 if (type1 == &PyLong_Type && !0) {
6780
6781 richcmpfunc frich = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6782
6783 if (frich != NULL) {
6784 PyObject *result = (*frich)(operand1, operand2, Py_GT);
6785
6786 if (result != Py_NotImplemented) {
6787 Py_LeaveRecursiveCall();
6788
6789 if (unlikely(result == NULL)) {
6790 return NUITKA_BOOL_EXCEPTION;
6791 }
6792
6793 {
6794 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6795 Py_DECREF(result);
6796 return r;
6797 }
6798 }
6799
6800 Py_DECREF_IMMORTAL(result);
6801 }
6802
6803 // No rich comparison worked, but maybe compare works.
6804 cmpfunc fcmp = PyLong_Type.tp_compare;
6805
6806 if (fcmp != NULL) {
6807 int c = (*fcmp)(operand1, operand2);
6808 c = adjust_tp_compare(c);
6809
6810 Py_LeaveRecursiveCall();
6811
6812 if (c == -2) {
6813 return NUITKA_BOOL_EXCEPTION;
6814 }
6815
6816 switch (Py_GT) {
6817 case Py_LT:
6818 c = c < 0;
6819 break;
6820 case Py_LE:
6821 c = c <= 0;
6822 break;
6823 case Py_EQ:
6824 c = c == 0;
6825 break;
6826 case Py_NE:
6827 c = c != 0;
6828 break;
6829 case Py_GT:
6830 c = c > 0;
6831 break;
6832 case Py_GE:
6833 c = c >= 0;
6834 break;
6835 default:
6836 NUITKA_CANNOT_GET_HERE("wrong op_code");
6837 }
6838
6839 bool r = c != 0;
6840 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6841
6842 return result;
6843 }
6844 }
6845
6846 // Fast path was not successful or not taken
6847 richcmpfunc f;
6848
6849 if (type1 != &PyLong_Type && 0) {
6850 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6851
6852 if (f != NULL) {
6853 PyObject *result = (*f)(operand2, operand1, Py_LT);
6854
6855 if (result != Py_NotImplemented) {
6856 Py_LeaveRecursiveCall();
6857
6858 if (unlikely(result == NULL)) {
6859 return NUITKA_BOOL_EXCEPTION;
6860 }
6861
6862 {
6863 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6864 Py_DECREF(result);
6865 return r;
6866 }
6867 }
6868
6869 Py_DECREF_IMMORTAL(result);
6870 }
6871 }
6872
6873 f = TP_RICHCOMPARE(type1);
6874 if (f != NULL) {
6875 PyObject *result = (*f)(operand1, operand2, Py_GT);
6876
6877 if (result != Py_NotImplemented) {
6878 Py_LeaveRecursiveCall();
6879
6880 if (unlikely(result == NULL)) {
6881 return NUITKA_BOOL_EXCEPTION;
6882 }
6883
6884 {
6885 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6886 Py_DECREF(result);
6887 return r;
6888 }
6889 }
6890
6891 Py_DECREF_IMMORTAL(result);
6892 }
6893
6894 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
6895 if (f != NULL) {
6896 PyObject *result = (*f)(operand2, operand1, Py_LT);
6897
6898 if (result != Py_NotImplemented) {
6899 Py_LeaveRecursiveCall();
6900
6901 if (unlikely(result == NULL)) {
6902 return NUITKA_BOOL_EXCEPTION;
6903 }
6904
6905 {
6906 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
6907 Py_DECREF(result);
6908 return r;
6909 }
6910 }
6911
6912 Py_DECREF_IMMORTAL(result);
6913 }
6914
6915 int c;
6916
6917 if (PyInstance_Check(operand1)) {
6918 cmpfunc fcmp = type1->tp_compare;
6919 c = (*fcmp)(operand1, operand2);
6920 } else if (0) {
6921 cmpfunc fcmp = PyLong_Type.tp_compare;
6922 c = (*fcmp)(operand1, operand2);
6923 } else {
6924 c = try_3way_compare(operand1, operand2);
6925 }
6926
6927 if (c >= 2) {
6928 if (type1 == &PyLong_Type) {
6929 Py_uintptr_t aa = (Py_uintptr_t)operand1;
6930 Py_uintptr_t bb = (Py_uintptr_t)operand2;
6931
6932 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6933 } else if (operand1 == Py_None) {
6934 // None is smaller than everything else
6935 c = -1;
6936 } else if (operand2 == Py_None) {
6937 // None is smaller than everything else
6938 c = 1;
6939 } else if (PyNumber_Check(operand1)) {
6940 // different type: compare type names but numbers are smaller than
6941 // others.
6942 if (PyNumber_Check(operand2)) {
6943 // Both numbers, need to make a decision based on types.
6944 Py_uintptr_t aa = (Py_uintptr_t)type1;
6945 Py_uintptr_t bb = (Py_uintptr_t)&PyLong_Type;
6946
6947 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6948 } else {
6949 c = -1;
6950 }
6951 } else if (PyNumber_Check(operand2)) {
6952 c = 1;
6953 } else {
6954 // Banking on C compile to optimize "strcmp".
6955 int s = strcmp(type1->tp_name, (PYTHON_VERSION < 0x300 ? "long" : "int"));
6956
6957 if (s < 0) {
6958 c = -1;
6959 } else if (s > 0) {
6960 c = 1;
6961 } else {
6962 // Same type name need to make a decision based on type address.
6963 Py_uintptr_t aa = (Py_uintptr_t)type1;
6964 Py_uintptr_t bb = (Py_uintptr_t)&PyLong_Type;
6965
6966 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
6967 }
6968 }
6969 }
6970
6971 Py_LeaveRecursiveCall();
6972
6973 if (unlikely(c <= -2)) {
6974 return NUITKA_BOOL_EXCEPTION;
6975 }
6976
6977 switch (Py_GT) {
6978 case Py_LT:
6979 c = c < 0;
6980 break;
6981 case Py_LE:
6982 c = c <= 0;
6983 break;
6984 case Py_EQ:
6985 c = c == 0;
6986 break;
6987 case Py_NE:
6988 c = c != 0;
6989 break;
6990 case Py_GT:
6991 c = c > 0;
6992 break;
6993 case Py_GE:
6994 c = c >= 0;
6995 break;
6996 }
6997
6998 bool r = c != 0;
6999 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7000
7001 return result;
7002#else
7003 bool checked_reverse_op = false;
7004 richcmpfunc f;
7005
7006 if (type1 != &PyLong_Type && Nuitka_Type_IsSubtype(&PyLong_Type, type1)) {
7007 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
7008
7009 if (f != NULL) {
7010 checked_reverse_op = true;
7011
7012 PyObject *result = (*f)(operand2, operand1, Py_LT);
7013
7014 if (result != Py_NotImplemented) {
7015 Py_LeaveRecursiveCall();
7016
7017 if (unlikely(result == NULL)) {
7018 return NUITKA_BOOL_EXCEPTION;
7019 }
7020
7021 {
7022 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7023 Py_DECREF(result);
7024 return r;
7025 }
7026 }
7027
7028 Py_DECREF_IMMORTAL(result);
7029 }
7030 }
7031
7032 f = TP_RICHCOMPARE(type1);
7033
7034 if (f != NULL) {
7035 PyObject *result = (*f)(operand1, operand2, Py_GT);
7036
7037 if (result != Py_NotImplemented) {
7038 Py_LeaveRecursiveCall();
7039
7040 if (unlikely(result == NULL)) {
7041 return NUITKA_BOOL_EXCEPTION;
7042 }
7043
7044 {
7045 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7046 Py_DECREF(result);
7047 return r;
7048 }
7049 }
7050
7051 Py_DECREF_IMMORTAL(result);
7052 }
7053
7054 if (checked_reverse_op == false) {
7055 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
7056
7057 if (f != NULL) {
7058 PyObject *result = (*f)(operand2, operand1, Py_LT);
7059
7060 if (result != Py_NotImplemented) {
7061 Py_LeaveRecursiveCall();
7062
7063 if (unlikely(result == NULL)) {
7064 return NUITKA_BOOL_EXCEPTION;
7065 }
7066
7067 {
7068 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7069 Py_DECREF(result);
7070 return r;
7071 }
7072 }
7073
7074 Py_DECREF_IMMORTAL(result);
7075 }
7076 }
7077
7078 Py_LeaveRecursiveCall();
7079
7080 // If it is not implemented, do pointer identity checks as "==" and "!=" and
7081 // otherwise give an error
7082 switch (Py_GT) {
7083 case Py_EQ: {
7084 bool r = operand1 == operand2;
7085 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7086
7087 return result;
7088 }
7089 case Py_NE: {
7090 bool r = operand1 != operand2;
7091 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7092
7093 return result;
7094 }
7095 default:
7096#if PYTHON_VERSION < 0x300
7097 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > long()", type1->tp_name);
7098#elif PYTHON_VERSION < 0x360
7099 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > int()", type1->tp_name);
7100#else
7101 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'int'", type1->tp_name);
7102#endif
7103 return NUITKA_BOOL_EXCEPTION;
7104 }
7105#endif
7106}
7107
7108/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
7109nuitka_bool RICH_COMPARE_GT_NBOOL_LONG_OBJECT(PyObject *operand1, PyObject *operand2) {
7110
7111 if (&PyLong_Type == Py_TYPE(operand2)) {
7112 return COMPARE_GT_CBOOL_LONG_LONG(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7113 }
7114
7115#if PYTHON_VERSION < 0x300
7116 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
7117 return NUITKA_BOOL_EXCEPTION;
7118 }
7119#else
7120 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
7121 return NUITKA_BOOL_EXCEPTION;
7122 }
7123#endif
7124
7125 PyTypeObject *type2 = Py_TYPE(operand2);
7126
7127#if PYTHON_VERSION < 0x300
7128 // If the types are equal, we may get away immediately except for instances.
7129 if (&PyLong_Type == type2 && !0) {
7130
7131 richcmpfunc frich = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
7132
7133 if (frich != NULL) {
7134 PyObject *result = (*frich)(operand1, operand2, Py_GT);
7135
7136 if (result != Py_NotImplemented) {
7137 Py_LeaveRecursiveCall();
7138
7139 if (unlikely(result == NULL)) {
7140 return NUITKA_BOOL_EXCEPTION;
7141 }
7142
7143 {
7144 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7145 Py_DECREF(result);
7146 return r;
7147 }
7148 }
7149
7150 Py_DECREF_IMMORTAL(result);
7151 }
7152
7153 // No rich comparison worked, but maybe compare works.
7154 cmpfunc fcmp = PyLong_Type.tp_compare;
7155
7156 if (fcmp != NULL) {
7157 int c = (*fcmp)(operand1, operand2);
7158 c = adjust_tp_compare(c);
7159
7160 Py_LeaveRecursiveCall();
7161
7162 if (c == -2) {
7163 return NUITKA_BOOL_EXCEPTION;
7164 }
7165
7166 switch (Py_GT) {
7167 case Py_LT:
7168 c = c < 0;
7169 break;
7170 case Py_LE:
7171 c = c <= 0;
7172 break;
7173 case Py_EQ:
7174 c = c == 0;
7175 break;
7176 case Py_NE:
7177 c = c != 0;
7178 break;
7179 case Py_GT:
7180 c = c > 0;
7181 break;
7182 case Py_GE:
7183 c = c >= 0;
7184 break;
7185 default:
7186 NUITKA_CANNOT_GET_HERE("wrong op_code");
7187 }
7188
7189 bool r = c != 0;
7190 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7191
7192 return result;
7193 }
7194 }
7195
7196 // Fast path was not successful or not taken
7197 richcmpfunc f;
7198
7199 if (&PyLong_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
7200 f = TP_RICHCOMPARE(type2);
7201
7202 if (f != NULL) {
7203 PyObject *result = (*f)(operand2, operand1, Py_LT);
7204
7205 if (result != Py_NotImplemented) {
7206 Py_LeaveRecursiveCall();
7207
7208 if (unlikely(result == NULL)) {
7209 return NUITKA_BOOL_EXCEPTION;
7210 }
7211
7212 {
7213 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7214 Py_DECREF(result);
7215 return r;
7216 }
7217 }
7218
7219 Py_DECREF_IMMORTAL(result);
7220 }
7221 }
7222
7223 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
7224 if (f != NULL) {
7225 PyObject *result = (*f)(operand1, operand2, Py_GT);
7226
7227 if (result != Py_NotImplemented) {
7228 Py_LeaveRecursiveCall();
7229
7230 if (unlikely(result == NULL)) {
7231 return NUITKA_BOOL_EXCEPTION;
7232 }
7233
7234 {
7235 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7236 Py_DECREF(result);
7237 return r;
7238 }
7239 }
7240
7241 Py_DECREF_IMMORTAL(result);
7242 }
7243
7244 f = TP_RICHCOMPARE(type2);
7245 if (f != NULL) {
7246 PyObject *result = (*f)(operand2, operand1, Py_LT);
7247
7248 if (result != Py_NotImplemented) {
7249 Py_LeaveRecursiveCall();
7250
7251 if (unlikely(result == NULL)) {
7252 return NUITKA_BOOL_EXCEPTION;
7253 }
7254
7255 {
7256 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7257 Py_DECREF(result);
7258 return r;
7259 }
7260 }
7261
7262 Py_DECREF_IMMORTAL(result);
7263 }
7264
7265 int c;
7266
7267 if (0) {
7268 cmpfunc fcmp = PyLong_Type.tp_compare;
7269 c = (*fcmp)(operand1, operand2);
7270 } else if (PyInstance_Check(operand2)) {
7271 cmpfunc fcmp = type2->tp_compare;
7272 c = (*fcmp)(operand1, operand2);
7273 } else {
7274 c = try_3way_compare(operand1, operand2);
7275 }
7276
7277 if (c >= 2) {
7278 if (&PyLong_Type == type2) {
7279 Py_uintptr_t aa = (Py_uintptr_t)operand1;
7280 Py_uintptr_t bb = (Py_uintptr_t)operand2;
7281
7282 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7283 } else if (operand1 == Py_None) {
7284 // None is smaller than everything else
7285 c = -1;
7286 } else if (operand2 == Py_None) {
7287 // None is smaller than everything else
7288 c = 1;
7289 } else if (PyNumber_Check(operand1)) {
7290 // different type: compare type names but numbers are smaller than
7291 // others.
7292 if (PyNumber_Check(operand2)) {
7293 // Both numbers, need to make a decision based on types.
7294 Py_uintptr_t aa = (Py_uintptr_t)&PyLong_Type;
7295 Py_uintptr_t bb = (Py_uintptr_t)type2;
7296
7297 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7298 } else {
7299 c = -1;
7300 }
7301 } else if (PyNumber_Check(operand2)) {
7302 c = 1;
7303 } else {
7304 // Banking on C compile to optimize "strcmp".
7305 int s = strcmp((PYTHON_VERSION < 0x300 ? "long" : "int"), type2->tp_name);
7306
7307 if (s < 0) {
7308 c = -1;
7309 } else if (s > 0) {
7310 c = 1;
7311 } else {
7312 // Same type name need to make a decision based on type address.
7313 Py_uintptr_t aa = (Py_uintptr_t)&PyLong_Type;
7314 Py_uintptr_t bb = (Py_uintptr_t)type2;
7315
7316 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7317 }
7318 }
7319 }
7320
7321 Py_LeaveRecursiveCall();
7322
7323 if (unlikely(c <= -2)) {
7324 return NUITKA_BOOL_EXCEPTION;
7325 }
7326
7327 switch (Py_GT) {
7328 case Py_LT:
7329 c = c < 0;
7330 break;
7331 case Py_LE:
7332 c = c <= 0;
7333 break;
7334 case Py_EQ:
7335 c = c == 0;
7336 break;
7337 case Py_NE:
7338 c = c != 0;
7339 break;
7340 case Py_GT:
7341 c = c > 0;
7342 break;
7343 case Py_GE:
7344 c = c >= 0;
7345 break;
7346 }
7347
7348 bool r = c != 0;
7349 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7350
7351 return result;
7352#else
7353 bool checked_reverse_op = false;
7354 richcmpfunc f;
7355
7356 if (&PyLong_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
7357 f = TP_RICHCOMPARE(type2);
7358
7359 if (f != NULL) {
7360 checked_reverse_op = true;
7361
7362 PyObject *result = (*f)(operand2, operand1, Py_LT);
7363
7364 if (result != Py_NotImplemented) {
7365 Py_LeaveRecursiveCall();
7366
7367 if (unlikely(result == NULL)) {
7368 return NUITKA_BOOL_EXCEPTION;
7369 }
7370
7371 {
7372 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7373 Py_DECREF(result);
7374 return r;
7375 }
7376 }
7377
7378 Py_DECREF_IMMORTAL(result);
7379 }
7380 }
7381
7382 f = (PYTHON_VERSION < 0x300 ? NULL : PyLong_Type.tp_richcompare);
7383
7384 if (f != NULL) {
7385 PyObject *result = (*f)(operand1, operand2, Py_GT);
7386
7387 if (result != Py_NotImplemented) {
7388 Py_LeaveRecursiveCall();
7389
7390 if (unlikely(result == NULL)) {
7391 return NUITKA_BOOL_EXCEPTION;
7392 }
7393
7394 {
7395 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7396 Py_DECREF(result);
7397 return r;
7398 }
7399 }
7400
7401 Py_DECREF_IMMORTAL(result);
7402 }
7403
7404 if (checked_reverse_op == false) {
7405 f = TP_RICHCOMPARE(type2);
7406
7407 if (f != NULL) {
7408 PyObject *result = (*f)(operand2, operand1, Py_LT);
7409
7410 if (result != Py_NotImplemented) {
7411 Py_LeaveRecursiveCall();
7412
7413 if (unlikely(result == NULL)) {
7414 return NUITKA_BOOL_EXCEPTION;
7415 }
7416
7417 {
7418 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7419 Py_DECREF(result);
7420 return r;
7421 }
7422 }
7423
7424 Py_DECREF_IMMORTAL(result);
7425 }
7426 }
7427
7428 Py_LeaveRecursiveCall();
7429
7430 // If it is not implemented, do pointer identity checks as "==" and "!=" and
7431 // otherwise give an error
7432 switch (Py_GT) {
7433 case Py_EQ: {
7434 bool r = operand1 == operand2;
7435 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7436
7437 return result;
7438 }
7439 case Py_NE: {
7440 bool r = operand1 != operand2;
7441 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
7442
7443 return result;
7444 }
7445 default:
7446#if PYTHON_VERSION < 0x300
7447 PyErr_Format(PyExc_TypeError, "unorderable types: long() > %s()", type2->tp_name);
7448#elif PYTHON_VERSION < 0x360
7449 PyErr_Format(PyExc_TypeError, "unorderable types: int() > %s()", type2->tp_name);
7450#else
7451 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'int' and '%s'", type2->tp_name);
7452#endif
7453 return NUITKA_BOOL_EXCEPTION;
7454 }
7455#endif
7456}
7457
7458static PyObject *COMPARE_GT_OBJECT_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
7459 CHECK_OBJECT(operand1);
7460 assert(PyFloat_CheckExact(operand1));
7461 CHECK_OBJECT(operand2);
7462 assert(PyFloat_CheckExact(operand2));
7463
7464 const double a = PyFloat_AS_DOUBLE(operand1);
7465 const double b = PyFloat_AS_DOUBLE(operand2);
7466
7467 bool r = a > b;
7468
7469 // Convert to target type.
7470 PyObject *result = BOOL_FROM(r);
7471 Py_INCREF_IMMORTAL(result);
7472 return result;
7473}
7474/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
7475PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
7476
7477 if (Py_TYPE(operand1) == &PyFloat_Type) {
7478 return COMPARE_GT_OBJECT_FLOAT_FLOAT(operand1, operand2);
7479 }
7480
7481#if PYTHON_VERSION < 0x300
7482 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
7483 return NULL;
7484 }
7485#else
7486 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
7487 return NULL;
7488 }
7489#endif
7490
7491 PyTypeObject *type1 = Py_TYPE(operand1);
7492
7493#if PYTHON_VERSION < 0x300
7494 // If the types are equal, we may get away immediately except for instances.
7495 if (type1 == &PyFloat_Type && !0) {
7496
7497 richcmpfunc frich = PyFloat_Type.tp_richcompare;
7498
7499 if (frich != NULL) {
7500 PyObject *result = (*frich)(operand1, operand2, Py_GT);
7501
7502 if (result != Py_NotImplemented) {
7503 Py_LeaveRecursiveCall();
7504
7505 return result;
7506 }
7507
7508 Py_DECREF_IMMORTAL(result);
7509 }
7510
7511 // No rich comparison worked, but maybe compare works.
7512 cmpfunc fcmp = NULL;
7513
7514 if (fcmp != NULL) {
7515 int c = (*fcmp)(operand1, operand2);
7516 c = adjust_tp_compare(c);
7517
7518 Py_LeaveRecursiveCall();
7519
7520 if (c == -2) {
7521 return NULL;
7522 }
7523
7524 switch (Py_GT) {
7525 case Py_LT:
7526 c = c < 0;
7527 break;
7528 case Py_LE:
7529 c = c <= 0;
7530 break;
7531 case Py_EQ:
7532 c = c == 0;
7533 break;
7534 case Py_NE:
7535 c = c != 0;
7536 break;
7537 case Py_GT:
7538 c = c > 0;
7539 break;
7540 case Py_GE:
7541 c = c >= 0;
7542 break;
7543 default:
7544 NUITKA_CANNOT_GET_HERE("wrong op_code");
7545 }
7546
7547 bool r = c != 0;
7548 PyObject *result = BOOL_FROM(r);
7549 Py_INCREF_IMMORTAL(result);
7550 return result;
7551 }
7552 }
7553
7554 // Fast path was not successful or not taken
7555 richcmpfunc f;
7556
7557 if (type1 != &PyFloat_Type && 0) {
7558 f = PyFloat_Type.tp_richcompare;
7559
7560 if (f != NULL) {
7561 PyObject *result = (*f)(operand2, operand1, Py_LT);
7562
7563 if (result != Py_NotImplemented) {
7564 Py_LeaveRecursiveCall();
7565
7566 return result;
7567 }
7568
7569 Py_DECREF_IMMORTAL(result);
7570 }
7571 }
7572
7573 f = TP_RICHCOMPARE(type1);
7574 if (f != NULL) {
7575 PyObject *result = (*f)(operand1, operand2, Py_GT);
7576
7577 if (result != Py_NotImplemented) {
7578 Py_LeaveRecursiveCall();
7579
7580 return result;
7581 }
7582
7583 Py_DECREF_IMMORTAL(result);
7584 }
7585
7586 f = PyFloat_Type.tp_richcompare;
7587 if (f != NULL) {
7588 PyObject *result = (*f)(operand2, operand1, Py_LT);
7589
7590 if (result != Py_NotImplemented) {
7591 Py_LeaveRecursiveCall();
7592
7593 return result;
7594 }
7595
7596 Py_DECREF_IMMORTAL(result);
7597 }
7598
7599 int c;
7600
7601 if (PyInstance_Check(operand1)) {
7602 cmpfunc fcmp = type1->tp_compare;
7603 c = (*fcmp)(operand1, operand2);
7604 } else if (0) {
7605 cmpfunc fcmp = NULL;
7606 c = (*fcmp)(operand1, operand2);
7607 } else {
7608 c = try_3way_compare(operand1, operand2);
7609 }
7610
7611 if (c >= 2) {
7612 if (type1 == &PyFloat_Type) {
7613 Py_uintptr_t aa = (Py_uintptr_t)operand1;
7614 Py_uintptr_t bb = (Py_uintptr_t)operand2;
7615
7616 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7617 } else if (operand1 == Py_None) {
7618 // None is smaller than everything else
7619 c = -1;
7620 } else if (operand2 == Py_None) {
7621 // None is smaller than everything else
7622 c = 1;
7623 } else if (PyNumber_Check(operand1)) {
7624 // different type: compare type names but numbers are smaller than
7625 // others.
7626 if (PyNumber_Check(operand2)) {
7627 // Both numbers, need to make a decision based on types.
7628 Py_uintptr_t aa = (Py_uintptr_t)type1;
7629 Py_uintptr_t bb = (Py_uintptr_t)&PyFloat_Type;
7630
7631 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7632 } else {
7633 c = -1;
7634 }
7635 } else if (PyNumber_Check(operand2)) {
7636 c = 1;
7637 } else {
7638 // Banking on C compile to optimize "strcmp".
7639 int s = strcmp(type1->tp_name, "float");
7640
7641 if (s < 0) {
7642 c = -1;
7643 } else if (s > 0) {
7644 c = 1;
7645 } else {
7646 // Same type name need to make a decision based on type address.
7647 Py_uintptr_t aa = (Py_uintptr_t)type1;
7648 Py_uintptr_t bb = (Py_uintptr_t)&PyFloat_Type;
7649
7650 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7651 }
7652 }
7653 }
7654
7655 Py_LeaveRecursiveCall();
7656
7657 if (unlikely(c <= -2)) {
7658 return NULL;
7659 }
7660
7661 switch (Py_GT) {
7662 case Py_LT:
7663 c = c < 0;
7664 break;
7665 case Py_LE:
7666 c = c <= 0;
7667 break;
7668 case Py_EQ:
7669 c = c == 0;
7670 break;
7671 case Py_NE:
7672 c = c != 0;
7673 break;
7674 case Py_GT:
7675 c = c > 0;
7676 break;
7677 case Py_GE:
7678 c = c >= 0;
7679 break;
7680 }
7681
7682 bool r = c != 0;
7683 PyObject *result = BOOL_FROM(r);
7684 Py_INCREF_IMMORTAL(result);
7685 return result;
7686#else
7687 bool checked_reverse_op = false;
7688 richcmpfunc f;
7689
7690 if (type1 != &PyFloat_Type && Nuitka_Type_IsSubtype(&PyFloat_Type, type1)) {
7691 f = PyFloat_Type.tp_richcompare;
7692
7693 if (f != NULL) {
7694 checked_reverse_op = true;
7695
7696 PyObject *result = (*f)(operand2, operand1, Py_LT);
7697
7698 if (result != Py_NotImplemented) {
7699 Py_LeaveRecursiveCall();
7700
7701 return result;
7702 }
7703
7704 Py_DECREF_IMMORTAL(result);
7705 }
7706 }
7707
7708 f = TP_RICHCOMPARE(type1);
7709
7710 if (f != NULL) {
7711 PyObject *result = (*f)(operand1, operand2, Py_GT);
7712
7713 if (result != Py_NotImplemented) {
7714 Py_LeaveRecursiveCall();
7715
7716 return result;
7717 }
7718
7719 Py_DECREF_IMMORTAL(result);
7720 }
7721
7722 if (checked_reverse_op == false) {
7723 f = PyFloat_Type.tp_richcompare;
7724
7725 if (f != NULL) {
7726 PyObject *result = (*f)(operand2, operand1, Py_LT);
7727
7728 if (result != Py_NotImplemented) {
7729 Py_LeaveRecursiveCall();
7730
7731 return result;
7732 }
7733
7734 Py_DECREF_IMMORTAL(result);
7735 }
7736 }
7737
7738 Py_LeaveRecursiveCall();
7739
7740 // If it is not implemented, do pointer identity checks as "==" and "!=" and
7741 // otherwise give an error
7742 switch (Py_GT) {
7743 case Py_EQ: {
7744 bool r = operand1 == operand2;
7745 PyObject *result = BOOL_FROM(r);
7746 Py_INCREF_IMMORTAL(result);
7747 return result;
7748 }
7749 case Py_NE: {
7750 bool r = operand1 != operand2;
7751 PyObject *result = BOOL_FROM(r);
7752 Py_INCREF_IMMORTAL(result);
7753 return result;
7754 }
7755 default:
7756#if PYTHON_VERSION < 0x360
7757 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > float()", type1->tp_name);
7758#else
7759 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'float'", type1->tp_name);
7760#endif
7761 return NULL;
7762 }
7763#endif
7764}
7765
7766/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
7767PyObject *RICH_COMPARE_GT_OBJECT_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
7768
7769 if (&PyFloat_Type == Py_TYPE(operand2)) {
7770 return COMPARE_GT_OBJECT_FLOAT_FLOAT(operand1, operand2);
7771 }
7772
7773#if PYTHON_VERSION < 0x300
7774 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
7775 return NULL;
7776 }
7777#else
7778 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
7779 return NULL;
7780 }
7781#endif
7782
7783 PyTypeObject *type2 = Py_TYPE(operand2);
7784
7785#if PYTHON_VERSION < 0x300
7786 // If the types are equal, we may get away immediately except for instances.
7787 if (&PyFloat_Type == type2 && !0) {
7788
7789 richcmpfunc frich = PyFloat_Type.tp_richcompare;
7790
7791 if (frich != NULL) {
7792 PyObject *result = (*frich)(operand1, operand2, Py_GT);
7793
7794 if (result != Py_NotImplemented) {
7795 Py_LeaveRecursiveCall();
7796
7797 return result;
7798 }
7799
7800 Py_DECREF_IMMORTAL(result);
7801 }
7802
7803 // No rich comparison worked, but maybe compare works.
7804 cmpfunc fcmp = NULL;
7805
7806 if (fcmp != NULL) {
7807 int c = (*fcmp)(operand1, operand2);
7808 c = adjust_tp_compare(c);
7809
7810 Py_LeaveRecursiveCall();
7811
7812 if (c == -2) {
7813 return NULL;
7814 }
7815
7816 switch (Py_GT) {
7817 case Py_LT:
7818 c = c < 0;
7819 break;
7820 case Py_LE:
7821 c = c <= 0;
7822 break;
7823 case Py_EQ:
7824 c = c == 0;
7825 break;
7826 case Py_NE:
7827 c = c != 0;
7828 break;
7829 case Py_GT:
7830 c = c > 0;
7831 break;
7832 case Py_GE:
7833 c = c >= 0;
7834 break;
7835 default:
7836 NUITKA_CANNOT_GET_HERE("wrong op_code");
7837 }
7838
7839 bool r = c != 0;
7840 PyObject *result = BOOL_FROM(r);
7841 Py_INCREF_IMMORTAL(result);
7842 return result;
7843 }
7844 }
7845
7846 // Fast path was not successful or not taken
7847 richcmpfunc f;
7848
7849 if (&PyFloat_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
7850 f = TP_RICHCOMPARE(type2);
7851
7852 if (f != NULL) {
7853 PyObject *result = (*f)(operand2, operand1, Py_LT);
7854
7855 if (result != Py_NotImplemented) {
7856 Py_LeaveRecursiveCall();
7857
7858 return result;
7859 }
7860
7861 Py_DECREF_IMMORTAL(result);
7862 }
7863 }
7864
7865 f = PyFloat_Type.tp_richcompare;
7866 if (f != NULL) {
7867 PyObject *result = (*f)(operand1, operand2, Py_GT);
7868
7869 if (result != Py_NotImplemented) {
7870 Py_LeaveRecursiveCall();
7871
7872 return result;
7873 }
7874
7875 Py_DECREF_IMMORTAL(result);
7876 }
7877
7878 f = TP_RICHCOMPARE(type2);
7879 if (f != NULL) {
7880 PyObject *result = (*f)(operand2, operand1, Py_LT);
7881
7882 if (result != Py_NotImplemented) {
7883 Py_LeaveRecursiveCall();
7884
7885 return result;
7886 }
7887
7888 Py_DECREF_IMMORTAL(result);
7889 }
7890
7891 int c;
7892
7893 if (0) {
7894 cmpfunc fcmp = NULL;
7895 c = (*fcmp)(operand1, operand2);
7896 } else if (PyInstance_Check(operand2)) {
7897 cmpfunc fcmp = type2->tp_compare;
7898 c = (*fcmp)(operand1, operand2);
7899 } else {
7900 c = try_3way_compare(operand1, operand2);
7901 }
7902
7903 if (c >= 2) {
7904 if (&PyFloat_Type == type2) {
7905 Py_uintptr_t aa = (Py_uintptr_t)operand1;
7906 Py_uintptr_t bb = (Py_uintptr_t)operand2;
7907
7908 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7909 } else if (operand1 == Py_None) {
7910 // None is smaller than everything else
7911 c = -1;
7912 } else if (operand2 == Py_None) {
7913 // None is smaller than everything else
7914 c = 1;
7915 } else if (PyNumber_Check(operand1)) {
7916 // different type: compare type names but numbers are smaller than
7917 // others.
7918 if (PyNumber_Check(operand2)) {
7919 // Both numbers, need to make a decision based on types.
7920 Py_uintptr_t aa = (Py_uintptr_t)&PyFloat_Type;
7921 Py_uintptr_t bb = (Py_uintptr_t)type2;
7922
7923 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7924 } else {
7925 c = -1;
7926 }
7927 } else if (PyNumber_Check(operand2)) {
7928 c = 1;
7929 } else {
7930 // Banking on C compile to optimize "strcmp".
7931 int s = strcmp("float", type2->tp_name);
7932
7933 if (s < 0) {
7934 c = -1;
7935 } else if (s > 0) {
7936 c = 1;
7937 } else {
7938 // Same type name need to make a decision based on type address.
7939 Py_uintptr_t aa = (Py_uintptr_t)&PyFloat_Type;
7940 Py_uintptr_t bb = (Py_uintptr_t)type2;
7941
7942 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
7943 }
7944 }
7945 }
7946
7947 Py_LeaveRecursiveCall();
7948
7949 if (unlikely(c <= -2)) {
7950 return NULL;
7951 }
7952
7953 switch (Py_GT) {
7954 case Py_LT:
7955 c = c < 0;
7956 break;
7957 case Py_LE:
7958 c = c <= 0;
7959 break;
7960 case Py_EQ:
7961 c = c == 0;
7962 break;
7963 case Py_NE:
7964 c = c != 0;
7965 break;
7966 case Py_GT:
7967 c = c > 0;
7968 break;
7969 case Py_GE:
7970 c = c >= 0;
7971 break;
7972 }
7973
7974 bool r = c != 0;
7975 PyObject *result = BOOL_FROM(r);
7976 Py_INCREF_IMMORTAL(result);
7977 return result;
7978#else
7979 bool checked_reverse_op = false;
7980 richcmpfunc f;
7981
7982 if (&PyFloat_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
7983 f = TP_RICHCOMPARE(type2);
7984
7985 if (f != NULL) {
7986 checked_reverse_op = true;
7987
7988 PyObject *result = (*f)(operand2, operand1, Py_LT);
7989
7990 if (result != Py_NotImplemented) {
7991 Py_LeaveRecursiveCall();
7992
7993 return result;
7994 }
7995
7996 Py_DECREF_IMMORTAL(result);
7997 }
7998 }
7999
8000 f = PyFloat_Type.tp_richcompare;
8001
8002 if (f != NULL) {
8003 PyObject *result = (*f)(operand1, operand2, Py_GT);
8004
8005 if (result != Py_NotImplemented) {
8006 Py_LeaveRecursiveCall();
8007
8008 return result;
8009 }
8010
8011 Py_DECREF_IMMORTAL(result);
8012 }
8013
8014 if (checked_reverse_op == false) {
8015 f = TP_RICHCOMPARE(type2);
8016
8017 if (f != NULL) {
8018 PyObject *result = (*f)(operand2, operand1, Py_LT);
8019
8020 if (result != Py_NotImplemented) {
8021 Py_LeaveRecursiveCall();
8022
8023 return result;
8024 }
8025
8026 Py_DECREF_IMMORTAL(result);
8027 }
8028 }
8029
8030 Py_LeaveRecursiveCall();
8031
8032 // If it is not implemented, do pointer identity checks as "==" and "!=" and
8033 // otherwise give an error
8034 switch (Py_GT) {
8035 case Py_EQ: {
8036 bool r = operand1 == operand2;
8037 PyObject *result = BOOL_FROM(r);
8038 Py_INCREF_IMMORTAL(result);
8039 return result;
8040 }
8041 case Py_NE: {
8042 bool r = operand1 != operand2;
8043 PyObject *result = BOOL_FROM(r);
8044 Py_INCREF_IMMORTAL(result);
8045 return result;
8046 }
8047 default:
8048#if PYTHON_VERSION < 0x360
8049 PyErr_Format(PyExc_TypeError, "unorderable types: float() > %s()", type2->tp_name);
8050#else
8051 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'float' and '%s'", type2->tp_name);
8052#endif
8053 return NULL;
8054 }
8055#endif
8056}
8057
8058static bool COMPARE_GT_CBOOL_FLOAT_FLOAT(PyObject *operand1, PyObject *operand2) {
8059 CHECK_OBJECT(operand1);
8060 assert(PyFloat_CheckExact(operand1));
8061 CHECK_OBJECT(operand2);
8062 assert(PyFloat_CheckExact(operand2));
8063
8064 const double a = PyFloat_AS_DOUBLE(operand1);
8065 const double b = PyFloat_AS_DOUBLE(operand2);
8066
8067 bool r = a > b;
8068
8069 // Convert to target type.
8070 bool result = r;
8071
8072 return result;
8073}
8074/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
8075nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_FLOAT(PyObject *operand1, PyObject *operand2) {
8076
8077 if (Py_TYPE(operand1) == &PyFloat_Type) {
8078 return COMPARE_GT_CBOOL_FLOAT_FLOAT(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8079 }
8080
8081#if PYTHON_VERSION < 0x300
8082 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
8083 return NUITKA_BOOL_EXCEPTION;
8084 }
8085#else
8086 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
8087 return NUITKA_BOOL_EXCEPTION;
8088 }
8089#endif
8090
8091 PyTypeObject *type1 = Py_TYPE(operand1);
8092
8093#if PYTHON_VERSION < 0x300
8094 // If the types are equal, we may get away immediately except for instances.
8095 if (type1 == &PyFloat_Type && !0) {
8096
8097 richcmpfunc frich = PyFloat_Type.tp_richcompare;
8098
8099 if (frich != NULL) {
8100 PyObject *result = (*frich)(operand1, operand2, Py_GT);
8101
8102 if (result != Py_NotImplemented) {
8103 Py_LeaveRecursiveCall();
8104
8105 if (unlikely(result == NULL)) {
8106 return NUITKA_BOOL_EXCEPTION;
8107 }
8108
8109 {
8110 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8111 Py_DECREF(result);
8112 return r;
8113 }
8114 }
8115
8116 Py_DECREF_IMMORTAL(result);
8117 }
8118
8119 // No rich comparison worked, but maybe compare works.
8120 cmpfunc fcmp = NULL;
8121
8122 if (fcmp != NULL) {
8123 int c = (*fcmp)(operand1, operand2);
8124 c = adjust_tp_compare(c);
8125
8126 Py_LeaveRecursiveCall();
8127
8128 if (c == -2) {
8129 return NUITKA_BOOL_EXCEPTION;
8130 }
8131
8132 switch (Py_GT) {
8133 case Py_LT:
8134 c = c < 0;
8135 break;
8136 case Py_LE:
8137 c = c <= 0;
8138 break;
8139 case Py_EQ:
8140 c = c == 0;
8141 break;
8142 case Py_NE:
8143 c = c != 0;
8144 break;
8145 case Py_GT:
8146 c = c > 0;
8147 break;
8148 case Py_GE:
8149 c = c >= 0;
8150 break;
8151 default:
8152 NUITKA_CANNOT_GET_HERE("wrong op_code");
8153 }
8154
8155 bool r = c != 0;
8156 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8157
8158 return result;
8159 }
8160 }
8161
8162 // Fast path was not successful or not taken
8163 richcmpfunc f;
8164
8165 if (type1 != &PyFloat_Type && 0) {
8166 f = PyFloat_Type.tp_richcompare;
8167
8168 if (f != NULL) {
8169 PyObject *result = (*f)(operand2, operand1, Py_LT);
8170
8171 if (result != Py_NotImplemented) {
8172 Py_LeaveRecursiveCall();
8173
8174 if (unlikely(result == NULL)) {
8175 return NUITKA_BOOL_EXCEPTION;
8176 }
8177
8178 {
8179 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8180 Py_DECREF(result);
8181 return r;
8182 }
8183 }
8184
8185 Py_DECREF_IMMORTAL(result);
8186 }
8187 }
8188
8189 f = TP_RICHCOMPARE(type1);
8190 if (f != NULL) {
8191 PyObject *result = (*f)(operand1, operand2, Py_GT);
8192
8193 if (result != Py_NotImplemented) {
8194 Py_LeaveRecursiveCall();
8195
8196 if (unlikely(result == NULL)) {
8197 return NUITKA_BOOL_EXCEPTION;
8198 }
8199
8200 {
8201 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8202 Py_DECREF(result);
8203 return r;
8204 }
8205 }
8206
8207 Py_DECREF_IMMORTAL(result);
8208 }
8209
8210 f = PyFloat_Type.tp_richcompare;
8211 if (f != NULL) {
8212 PyObject *result = (*f)(operand2, operand1, Py_LT);
8213
8214 if (result != Py_NotImplemented) {
8215 Py_LeaveRecursiveCall();
8216
8217 if (unlikely(result == NULL)) {
8218 return NUITKA_BOOL_EXCEPTION;
8219 }
8220
8221 {
8222 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8223 Py_DECREF(result);
8224 return r;
8225 }
8226 }
8227
8228 Py_DECREF_IMMORTAL(result);
8229 }
8230
8231 int c;
8232
8233 if (PyInstance_Check(operand1)) {
8234 cmpfunc fcmp = type1->tp_compare;
8235 c = (*fcmp)(operand1, operand2);
8236 } else if (0) {
8237 cmpfunc fcmp = NULL;
8238 c = (*fcmp)(operand1, operand2);
8239 } else {
8240 c = try_3way_compare(operand1, operand2);
8241 }
8242
8243 if (c >= 2) {
8244 if (type1 == &PyFloat_Type) {
8245 Py_uintptr_t aa = (Py_uintptr_t)operand1;
8246 Py_uintptr_t bb = (Py_uintptr_t)operand2;
8247
8248 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8249 } else if (operand1 == Py_None) {
8250 // None is smaller than everything else
8251 c = -1;
8252 } else if (operand2 == Py_None) {
8253 // None is smaller than everything else
8254 c = 1;
8255 } else if (PyNumber_Check(operand1)) {
8256 // different type: compare type names but numbers are smaller than
8257 // others.
8258 if (PyNumber_Check(operand2)) {
8259 // Both numbers, need to make a decision based on types.
8260 Py_uintptr_t aa = (Py_uintptr_t)type1;
8261 Py_uintptr_t bb = (Py_uintptr_t)&PyFloat_Type;
8262
8263 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8264 } else {
8265 c = -1;
8266 }
8267 } else if (PyNumber_Check(operand2)) {
8268 c = 1;
8269 } else {
8270 // Banking on C compile to optimize "strcmp".
8271 int s = strcmp(type1->tp_name, "float");
8272
8273 if (s < 0) {
8274 c = -1;
8275 } else if (s > 0) {
8276 c = 1;
8277 } else {
8278 // Same type name need to make a decision based on type address.
8279 Py_uintptr_t aa = (Py_uintptr_t)type1;
8280 Py_uintptr_t bb = (Py_uintptr_t)&PyFloat_Type;
8281
8282 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8283 }
8284 }
8285 }
8286
8287 Py_LeaveRecursiveCall();
8288
8289 if (unlikely(c <= -2)) {
8290 return NUITKA_BOOL_EXCEPTION;
8291 }
8292
8293 switch (Py_GT) {
8294 case Py_LT:
8295 c = c < 0;
8296 break;
8297 case Py_LE:
8298 c = c <= 0;
8299 break;
8300 case Py_EQ:
8301 c = c == 0;
8302 break;
8303 case Py_NE:
8304 c = c != 0;
8305 break;
8306 case Py_GT:
8307 c = c > 0;
8308 break;
8309 case Py_GE:
8310 c = c >= 0;
8311 break;
8312 }
8313
8314 bool r = c != 0;
8315 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8316
8317 return result;
8318#else
8319 bool checked_reverse_op = false;
8320 richcmpfunc f;
8321
8322 if (type1 != &PyFloat_Type && Nuitka_Type_IsSubtype(&PyFloat_Type, type1)) {
8323 f = PyFloat_Type.tp_richcompare;
8324
8325 if (f != NULL) {
8326 checked_reverse_op = true;
8327
8328 PyObject *result = (*f)(operand2, operand1, Py_LT);
8329
8330 if (result != Py_NotImplemented) {
8331 Py_LeaveRecursiveCall();
8332
8333 if (unlikely(result == NULL)) {
8334 return NUITKA_BOOL_EXCEPTION;
8335 }
8336
8337 {
8338 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8339 Py_DECREF(result);
8340 return r;
8341 }
8342 }
8343
8344 Py_DECREF_IMMORTAL(result);
8345 }
8346 }
8347
8348 f = TP_RICHCOMPARE(type1);
8349
8350 if (f != NULL) {
8351 PyObject *result = (*f)(operand1, operand2, Py_GT);
8352
8353 if (result != Py_NotImplemented) {
8354 Py_LeaveRecursiveCall();
8355
8356 if (unlikely(result == NULL)) {
8357 return NUITKA_BOOL_EXCEPTION;
8358 }
8359
8360 {
8361 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8362 Py_DECREF(result);
8363 return r;
8364 }
8365 }
8366
8367 Py_DECREF_IMMORTAL(result);
8368 }
8369
8370 if (checked_reverse_op == false) {
8371 f = PyFloat_Type.tp_richcompare;
8372
8373 if (f != NULL) {
8374 PyObject *result = (*f)(operand2, operand1, Py_LT);
8375
8376 if (result != Py_NotImplemented) {
8377 Py_LeaveRecursiveCall();
8378
8379 if (unlikely(result == NULL)) {
8380 return NUITKA_BOOL_EXCEPTION;
8381 }
8382
8383 {
8384 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8385 Py_DECREF(result);
8386 return r;
8387 }
8388 }
8389
8390 Py_DECREF_IMMORTAL(result);
8391 }
8392 }
8393
8394 Py_LeaveRecursiveCall();
8395
8396 // If it is not implemented, do pointer identity checks as "==" and "!=" and
8397 // otherwise give an error
8398 switch (Py_GT) {
8399 case Py_EQ: {
8400 bool r = operand1 == operand2;
8401 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8402
8403 return result;
8404 }
8405 case Py_NE: {
8406 bool r = operand1 != operand2;
8407 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8408
8409 return result;
8410 }
8411 default:
8412#if PYTHON_VERSION < 0x360
8413 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > float()", type1->tp_name);
8414#else
8415 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'float'", type1->tp_name);
8416#endif
8417 return NUITKA_BOOL_EXCEPTION;
8418 }
8419#endif
8420}
8421
8422/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
8423nuitka_bool RICH_COMPARE_GT_NBOOL_FLOAT_OBJECT(PyObject *operand1, PyObject *operand2) {
8424
8425 if (&PyFloat_Type == Py_TYPE(operand2)) {
8426 return COMPARE_GT_CBOOL_FLOAT_FLOAT(operand1, operand2) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8427 }
8428
8429#if PYTHON_VERSION < 0x300
8430 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
8431 return NUITKA_BOOL_EXCEPTION;
8432 }
8433#else
8434 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
8435 return NUITKA_BOOL_EXCEPTION;
8436 }
8437#endif
8438
8439 PyTypeObject *type2 = Py_TYPE(operand2);
8440
8441#if PYTHON_VERSION < 0x300
8442 // If the types are equal, we may get away immediately except for instances.
8443 if (&PyFloat_Type == type2 && !0) {
8444
8445 richcmpfunc frich = PyFloat_Type.tp_richcompare;
8446
8447 if (frich != NULL) {
8448 PyObject *result = (*frich)(operand1, operand2, Py_GT);
8449
8450 if (result != Py_NotImplemented) {
8451 Py_LeaveRecursiveCall();
8452
8453 if (unlikely(result == NULL)) {
8454 return NUITKA_BOOL_EXCEPTION;
8455 }
8456
8457 {
8458 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8459 Py_DECREF(result);
8460 return r;
8461 }
8462 }
8463
8464 Py_DECREF_IMMORTAL(result);
8465 }
8466
8467 // No rich comparison worked, but maybe compare works.
8468 cmpfunc fcmp = NULL;
8469
8470 if (fcmp != NULL) {
8471 int c = (*fcmp)(operand1, operand2);
8472 c = adjust_tp_compare(c);
8473
8474 Py_LeaveRecursiveCall();
8475
8476 if (c == -2) {
8477 return NUITKA_BOOL_EXCEPTION;
8478 }
8479
8480 switch (Py_GT) {
8481 case Py_LT:
8482 c = c < 0;
8483 break;
8484 case Py_LE:
8485 c = c <= 0;
8486 break;
8487 case Py_EQ:
8488 c = c == 0;
8489 break;
8490 case Py_NE:
8491 c = c != 0;
8492 break;
8493 case Py_GT:
8494 c = c > 0;
8495 break;
8496 case Py_GE:
8497 c = c >= 0;
8498 break;
8499 default:
8500 NUITKA_CANNOT_GET_HERE("wrong op_code");
8501 }
8502
8503 bool r = c != 0;
8504 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8505
8506 return result;
8507 }
8508 }
8509
8510 // Fast path was not successful or not taken
8511 richcmpfunc f;
8512
8513 if (&PyFloat_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
8514 f = TP_RICHCOMPARE(type2);
8515
8516 if (f != NULL) {
8517 PyObject *result = (*f)(operand2, operand1, Py_LT);
8518
8519 if (result != Py_NotImplemented) {
8520 Py_LeaveRecursiveCall();
8521
8522 if (unlikely(result == NULL)) {
8523 return NUITKA_BOOL_EXCEPTION;
8524 }
8525
8526 {
8527 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8528 Py_DECREF(result);
8529 return r;
8530 }
8531 }
8532
8533 Py_DECREF_IMMORTAL(result);
8534 }
8535 }
8536
8537 f = PyFloat_Type.tp_richcompare;
8538 if (f != NULL) {
8539 PyObject *result = (*f)(operand1, operand2, Py_GT);
8540
8541 if (result != Py_NotImplemented) {
8542 Py_LeaveRecursiveCall();
8543
8544 if (unlikely(result == NULL)) {
8545 return NUITKA_BOOL_EXCEPTION;
8546 }
8547
8548 {
8549 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8550 Py_DECREF(result);
8551 return r;
8552 }
8553 }
8554
8555 Py_DECREF_IMMORTAL(result);
8556 }
8557
8558 f = TP_RICHCOMPARE(type2);
8559 if (f != NULL) {
8560 PyObject *result = (*f)(operand2, operand1, Py_LT);
8561
8562 if (result != Py_NotImplemented) {
8563 Py_LeaveRecursiveCall();
8564
8565 if (unlikely(result == NULL)) {
8566 return NUITKA_BOOL_EXCEPTION;
8567 }
8568
8569 {
8570 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8571 Py_DECREF(result);
8572 return r;
8573 }
8574 }
8575
8576 Py_DECREF_IMMORTAL(result);
8577 }
8578
8579 int c;
8580
8581 if (0) {
8582 cmpfunc fcmp = NULL;
8583 c = (*fcmp)(operand1, operand2);
8584 } else if (PyInstance_Check(operand2)) {
8585 cmpfunc fcmp = type2->tp_compare;
8586 c = (*fcmp)(operand1, operand2);
8587 } else {
8588 c = try_3way_compare(operand1, operand2);
8589 }
8590
8591 if (c >= 2) {
8592 if (&PyFloat_Type == type2) {
8593 Py_uintptr_t aa = (Py_uintptr_t)operand1;
8594 Py_uintptr_t bb = (Py_uintptr_t)operand2;
8595
8596 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8597 } else if (operand1 == Py_None) {
8598 // None is smaller than everything else
8599 c = -1;
8600 } else if (operand2 == Py_None) {
8601 // None is smaller than everything else
8602 c = 1;
8603 } else if (PyNumber_Check(operand1)) {
8604 // different type: compare type names but numbers are smaller than
8605 // others.
8606 if (PyNumber_Check(operand2)) {
8607 // Both numbers, need to make a decision based on types.
8608 Py_uintptr_t aa = (Py_uintptr_t)&PyFloat_Type;
8609 Py_uintptr_t bb = (Py_uintptr_t)type2;
8610
8611 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8612 } else {
8613 c = -1;
8614 }
8615 } else if (PyNumber_Check(operand2)) {
8616 c = 1;
8617 } else {
8618 // Banking on C compile to optimize "strcmp".
8619 int s = strcmp("float", type2->tp_name);
8620
8621 if (s < 0) {
8622 c = -1;
8623 } else if (s > 0) {
8624 c = 1;
8625 } else {
8626 // Same type name need to make a decision based on type address.
8627 Py_uintptr_t aa = (Py_uintptr_t)&PyFloat_Type;
8628 Py_uintptr_t bb = (Py_uintptr_t)type2;
8629
8630 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8631 }
8632 }
8633 }
8634
8635 Py_LeaveRecursiveCall();
8636
8637 if (unlikely(c <= -2)) {
8638 return NUITKA_BOOL_EXCEPTION;
8639 }
8640
8641 switch (Py_GT) {
8642 case Py_LT:
8643 c = c < 0;
8644 break;
8645 case Py_LE:
8646 c = c <= 0;
8647 break;
8648 case Py_EQ:
8649 c = c == 0;
8650 break;
8651 case Py_NE:
8652 c = c != 0;
8653 break;
8654 case Py_GT:
8655 c = c > 0;
8656 break;
8657 case Py_GE:
8658 c = c >= 0;
8659 break;
8660 }
8661
8662 bool r = c != 0;
8663 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8664
8665 return result;
8666#else
8667 bool checked_reverse_op = false;
8668 richcmpfunc f;
8669
8670 if (&PyFloat_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
8671 f = TP_RICHCOMPARE(type2);
8672
8673 if (f != NULL) {
8674 checked_reverse_op = true;
8675
8676 PyObject *result = (*f)(operand2, operand1, Py_LT);
8677
8678 if (result != Py_NotImplemented) {
8679 Py_LeaveRecursiveCall();
8680
8681 if (unlikely(result == NULL)) {
8682 return NUITKA_BOOL_EXCEPTION;
8683 }
8684
8685 {
8686 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8687 Py_DECREF(result);
8688 return r;
8689 }
8690 }
8691
8692 Py_DECREF_IMMORTAL(result);
8693 }
8694 }
8695
8696 f = PyFloat_Type.tp_richcompare;
8697
8698 if (f != NULL) {
8699 PyObject *result = (*f)(operand1, operand2, Py_GT);
8700
8701 if (result != Py_NotImplemented) {
8702 Py_LeaveRecursiveCall();
8703
8704 if (unlikely(result == NULL)) {
8705 return NUITKA_BOOL_EXCEPTION;
8706 }
8707
8708 {
8709 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8710 Py_DECREF(result);
8711 return r;
8712 }
8713 }
8714
8715 Py_DECREF_IMMORTAL(result);
8716 }
8717
8718 if (checked_reverse_op == false) {
8719 f = TP_RICHCOMPARE(type2);
8720
8721 if (f != NULL) {
8722 PyObject *result = (*f)(operand2, operand1, Py_LT);
8723
8724 if (result != Py_NotImplemented) {
8725 Py_LeaveRecursiveCall();
8726
8727 if (unlikely(result == NULL)) {
8728 return NUITKA_BOOL_EXCEPTION;
8729 }
8730
8731 {
8732 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8733 Py_DECREF(result);
8734 return r;
8735 }
8736 }
8737
8738 Py_DECREF_IMMORTAL(result);
8739 }
8740 }
8741
8742 Py_LeaveRecursiveCall();
8743
8744 // If it is not implemented, do pointer identity checks as "==" and "!=" and
8745 // otherwise give an error
8746 switch (Py_GT) {
8747 case Py_EQ: {
8748 bool r = operand1 == operand2;
8749 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8750
8751 return result;
8752 }
8753 case Py_NE: {
8754 bool r = operand1 != operand2;
8755 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
8756
8757 return result;
8758 }
8759 default:
8760#if PYTHON_VERSION < 0x360
8761 PyErr_Format(PyExc_TypeError, "unorderable types: float() > %s()", type2->tp_name);
8762#else
8763 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'float' and '%s'", type2->tp_name);
8764#endif
8765 return NUITKA_BOOL_EXCEPTION;
8766 }
8767#endif
8768}
8769
8770static PyObject *COMPARE_GT_OBJECT_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
8771 CHECK_OBJECT(operand1);
8772 assert(PyTuple_CheckExact(operand1));
8773 CHECK_OBJECT(operand2);
8774 assert(PyTuple_CheckExact(operand2));
8775
8776 PyTupleObject *a = (PyTupleObject *)operand1;
8777 PyTupleObject *b = (PyTupleObject *)operand2;
8778
8779 Py_ssize_t len_a = Py_SIZE(a);
8780 Py_ssize_t len_b = Py_SIZE(b);
8781
8782 bool found = false;
8783 nuitka_bool res = NUITKA_BOOL_TRUE;
8784
8785 Py_ssize_t i;
8786 for (i = 0; i < len_a && i < len_b; i++) {
8787 PyObject *aa = a->ob_item[i];
8788 PyObject *bb = b->ob_item[i];
8789
8790 if (aa == bb) {
8791 continue;
8792 }
8793
8794 res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(aa, bb);
8795
8796 if (res == NUITKA_BOOL_EXCEPTION) {
8797 return NULL;
8798 }
8799
8800 if (res == NUITKA_BOOL_FALSE) {
8801 found = true;
8802 break;
8803 }
8804 }
8805
8806 if (found == false) {
8807 bool r = len_a > len_b;
8808
8809 // Convert to target type.
8810 PyObject *result = BOOL_FROM(r);
8811 Py_INCREF_IMMORTAL(result);
8812 return result;
8813 }
8814
8815 return RICH_COMPARE_GT_OBJECT_OBJECT_OBJECT(a->ob_item[i], b->ob_item[i]);
8816}
8817/* Code referring to "OBJECT" corresponds to any Python object and "TUPLE" to Python 'tuple'. */
8818PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_TUPLE(PyObject *operand1, PyObject *operand2) {
8819
8820 if (Py_TYPE(operand1) == &PyTuple_Type) {
8821 return COMPARE_GT_OBJECT_TUPLE_TUPLE(operand1, operand2);
8822 }
8823
8824#if PYTHON_VERSION < 0x300
8825 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
8826 return NULL;
8827 }
8828#else
8829 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
8830 return NULL;
8831 }
8832#endif
8833
8834 PyTypeObject *type1 = Py_TYPE(operand1);
8835
8836#if PYTHON_VERSION < 0x300
8837 // If the types are equal, we may get away immediately except for instances.
8838 if (type1 == &PyTuple_Type && !0) {
8839
8840 richcmpfunc frich = PyTuple_Type.tp_richcompare;
8841
8842 if (frich != NULL) {
8843 PyObject *result = (*frich)(operand1, operand2, Py_GT);
8844
8845 if (result != Py_NotImplemented) {
8846 Py_LeaveRecursiveCall();
8847
8848 return result;
8849 }
8850
8851 Py_DECREF_IMMORTAL(result);
8852 }
8853
8854 // No rich comparison worked, but maybe compare works.
8855 cmpfunc fcmp = NULL;
8856
8857 if (fcmp != NULL) {
8858 int c = (*fcmp)(operand1, operand2);
8859 c = adjust_tp_compare(c);
8860
8861 Py_LeaveRecursiveCall();
8862
8863 if (c == -2) {
8864 return NULL;
8865 }
8866
8867 switch (Py_GT) {
8868 case Py_LT:
8869 c = c < 0;
8870 break;
8871 case Py_LE:
8872 c = c <= 0;
8873 break;
8874 case Py_EQ:
8875 c = c == 0;
8876 break;
8877 case Py_NE:
8878 c = c != 0;
8879 break;
8880 case Py_GT:
8881 c = c > 0;
8882 break;
8883 case Py_GE:
8884 c = c >= 0;
8885 break;
8886 default:
8887 NUITKA_CANNOT_GET_HERE("wrong op_code");
8888 }
8889
8890 bool r = c != 0;
8891 PyObject *result = BOOL_FROM(r);
8892 Py_INCREF_IMMORTAL(result);
8893 return result;
8894 }
8895 }
8896
8897 // Fast path was not successful or not taken
8898 richcmpfunc f;
8899
8900 if (type1 != &PyTuple_Type && 0) {
8901 f = PyTuple_Type.tp_richcompare;
8902
8903 if (f != NULL) {
8904 PyObject *result = (*f)(operand2, operand1, Py_LT);
8905
8906 if (result != Py_NotImplemented) {
8907 Py_LeaveRecursiveCall();
8908
8909 return result;
8910 }
8911
8912 Py_DECREF_IMMORTAL(result);
8913 }
8914 }
8915
8916 f = TP_RICHCOMPARE(type1);
8917 if (f != NULL) {
8918 PyObject *result = (*f)(operand1, operand2, Py_GT);
8919
8920 if (result != Py_NotImplemented) {
8921 Py_LeaveRecursiveCall();
8922
8923 return result;
8924 }
8925
8926 Py_DECREF_IMMORTAL(result);
8927 }
8928
8929 f = PyTuple_Type.tp_richcompare;
8930 if (f != NULL) {
8931 PyObject *result = (*f)(operand2, operand1, Py_LT);
8932
8933 if (result != Py_NotImplemented) {
8934 Py_LeaveRecursiveCall();
8935
8936 return result;
8937 }
8938
8939 Py_DECREF_IMMORTAL(result);
8940 }
8941
8942 int c;
8943
8944 if (PyInstance_Check(operand1)) {
8945 cmpfunc fcmp = type1->tp_compare;
8946 c = (*fcmp)(operand1, operand2);
8947 } else if (0) {
8948 cmpfunc fcmp = NULL;
8949 c = (*fcmp)(operand1, operand2);
8950 } else {
8951 c = try_3way_compare(operand1, operand2);
8952 }
8953
8954 if (c >= 2) {
8955 if (type1 == &PyTuple_Type) {
8956 Py_uintptr_t aa = (Py_uintptr_t)operand1;
8957 Py_uintptr_t bb = (Py_uintptr_t)operand2;
8958
8959 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8960 } else if (operand1 == Py_None) {
8961 // None is smaller than everything else
8962 c = -1;
8963 } else if (operand2 == Py_None) {
8964 // None is smaller than everything else
8965 c = 1;
8966 } else if (PyNumber_Check(operand1)) {
8967 // different type: compare type names but numbers are smaller than
8968 // others.
8969 if (PyNumber_Check(operand2)) {
8970 // Both numbers, need to make a decision based on types.
8971 Py_uintptr_t aa = (Py_uintptr_t)type1;
8972 Py_uintptr_t bb = (Py_uintptr_t)&PyTuple_Type;
8973
8974 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8975 } else {
8976 c = -1;
8977 }
8978 } else if (PyNumber_Check(operand2)) {
8979 c = 1;
8980 } else {
8981 // Banking on C compile to optimize "strcmp".
8982 int s = strcmp(type1->tp_name, "tuple");
8983
8984 if (s < 0) {
8985 c = -1;
8986 } else if (s > 0) {
8987 c = 1;
8988 } else {
8989 // Same type name need to make a decision based on type address.
8990 Py_uintptr_t aa = (Py_uintptr_t)type1;
8991 Py_uintptr_t bb = (Py_uintptr_t)&PyTuple_Type;
8992
8993 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
8994 }
8995 }
8996 }
8997
8998 Py_LeaveRecursiveCall();
8999
9000 if (unlikely(c <= -2)) {
9001 return NULL;
9002 }
9003
9004 switch (Py_GT) {
9005 case Py_LT:
9006 c = c < 0;
9007 break;
9008 case Py_LE:
9009 c = c <= 0;
9010 break;
9011 case Py_EQ:
9012 c = c == 0;
9013 break;
9014 case Py_NE:
9015 c = c != 0;
9016 break;
9017 case Py_GT:
9018 c = c > 0;
9019 break;
9020 case Py_GE:
9021 c = c >= 0;
9022 break;
9023 }
9024
9025 bool r = c != 0;
9026 PyObject *result = BOOL_FROM(r);
9027 Py_INCREF_IMMORTAL(result);
9028 return result;
9029#else
9030 bool checked_reverse_op = false;
9031 richcmpfunc f;
9032
9033 if (type1 != &PyTuple_Type && Nuitka_Type_IsSubtype(&PyTuple_Type, type1)) {
9034 f = PyTuple_Type.tp_richcompare;
9035
9036 if (f != NULL) {
9037 checked_reverse_op = true;
9038
9039 PyObject *result = (*f)(operand2, operand1, Py_LT);
9040
9041 if (result != Py_NotImplemented) {
9042 Py_LeaveRecursiveCall();
9043
9044 return result;
9045 }
9046
9047 Py_DECREF_IMMORTAL(result);
9048 }
9049 }
9050
9051 f = TP_RICHCOMPARE(type1);
9052
9053 if (f != NULL) {
9054 PyObject *result = (*f)(operand1, operand2, Py_GT);
9055
9056 if (result != Py_NotImplemented) {
9057 Py_LeaveRecursiveCall();
9058
9059 return result;
9060 }
9061
9062 Py_DECREF_IMMORTAL(result);
9063 }
9064
9065 if (checked_reverse_op == false) {
9066 f = PyTuple_Type.tp_richcompare;
9067
9068 if (f != NULL) {
9069 PyObject *result = (*f)(operand2, operand1, Py_LT);
9070
9071 if (result != Py_NotImplemented) {
9072 Py_LeaveRecursiveCall();
9073
9074 return result;
9075 }
9076
9077 Py_DECREF_IMMORTAL(result);
9078 }
9079 }
9080
9081 Py_LeaveRecursiveCall();
9082
9083 // If it is not implemented, do pointer identity checks as "==" and "!=" and
9084 // otherwise give an error
9085 switch (Py_GT) {
9086 case Py_EQ: {
9087 bool r = operand1 == operand2;
9088 PyObject *result = BOOL_FROM(r);
9089 Py_INCREF_IMMORTAL(result);
9090 return result;
9091 }
9092 case Py_NE: {
9093 bool r = operand1 != operand2;
9094 PyObject *result = BOOL_FROM(r);
9095 Py_INCREF_IMMORTAL(result);
9096 return result;
9097 }
9098 default:
9099#if PYTHON_VERSION < 0x360
9100 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > tuple()", type1->tp_name);
9101#else
9102 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'tuple'", type1->tp_name);
9103#endif
9104 return NULL;
9105 }
9106#endif
9107}
9108
9109/* Code referring to "TUPLE" corresponds to Python 'tuple' and "OBJECT" to any Python object. */
9110PyObject *RICH_COMPARE_GT_OBJECT_TUPLE_OBJECT(PyObject *operand1, PyObject *operand2) {
9111
9112 if (&PyTuple_Type == Py_TYPE(operand2)) {
9113 return COMPARE_GT_OBJECT_TUPLE_TUPLE(operand1, operand2);
9114 }
9115
9116#if PYTHON_VERSION < 0x300
9117 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
9118 return NULL;
9119 }
9120#else
9121 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
9122 return NULL;
9123 }
9124#endif
9125
9126 PyTypeObject *type2 = Py_TYPE(operand2);
9127
9128#if PYTHON_VERSION < 0x300
9129 // If the types are equal, we may get away immediately except for instances.
9130 if (&PyTuple_Type == type2 && !0) {
9131
9132 richcmpfunc frich = PyTuple_Type.tp_richcompare;
9133
9134 if (frich != NULL) {
9135 PyObject *result = (*frich)(operand1, operand2, Py_GT);
9136
9137 if (result != Py_NotImplemented) {
9138 Py_LeaveRecursiveCall();
9139
9140 return result;
9141 }
9142
9143 Py_DECREF_IMMORTAL(result);
9144 }
9145
9146 // No rich comparison worked, but maybe compare works.
9147 cmpfunc fcmp = NULL;
9148
9149 if (fcmp != NULL) {
9150 int c = (*fcmp)(operand1, operand2);
9151 c = adjust_tp_compare(c);
9152
9153 Py_LeaveRecursiveCall();
9154
9155 if (c == -2) {
9156 return NULL;
9157 }
9158
9159 switch (Py_GT) {
9160 case Py_LT:
9161 c = c < 0;
9162 break;
9163 case Py_LE:
9164 c = c <= 0;
9165 break;
9166 case Py_EQ:
9167 c = c == 0;
9168 break;
9169 case Py_NE:
9170 c = c != 0;
9171 break;
9172 case Py_GT:
9173 c = c > 0;
9174 break;
9175 case Py_GE:
9176 c = c >= 0;
9177 break;
9178 default:
9179 NUITKA_CANNOT_GET_HERE("wrong op_code");
9180 }
9181
9182 bool r = c != 0;
9183 PyObject *result = BOOL_FROM(r);
9184 Py_INCREF_IMMORTAL(result);
9185 return result;
9186 }
9187 }
9188
9189 // Fast path was not successful or not taken
9190 richcmpfunc f;
9191
9192 if (&PyTuple_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyTuple_Type)) {
9193 f = TP_RICHCOMPARE(type2);
9194
9195 if (f != NULL) {
9196 PyObject *result = (*f)(operand2, operand1, Py_LT);
9197
9198 if (result != Py_NotImplemented) {
9199 Py_LeaveRecursiveCall();
9200
9201 return result;
9202 }
9203
9204 Py_DECREF_IMMORTAL(result);
9205 }
9206 }
9207
9208 f = PyTuple_Type.tp_richcompare;
9209 if (f != NULL) {
9210 PyObject *result = (*f)(operand1, operand2, Py_GT);
9211
9212 if (result != Py_NotImplemented) {
9213 Py_LeaveRecursiveCall();
9214
9215 return result;
9216 }
9217
9218 Py_DECREF_IMMORTAL(result);
9219 }
9220
9221 f = TP_RICHCOMPARE(type2);
9222 if (f != NULL) {
9223 PyObject *result = (*f)(operand2, operand1, Py_LT);
9224
9225 if (result != Py_NotImplemented) {
9226 Py_LeaveRecursiveCall();
9227
9228 return result;
9229 }
9230
9231 Py_DECREF_IMMORTAL(result);
9232 }
9233
9234 int c;
9235
9236 if (0) {
9237 cmpfunc fcmp = NULL;
9238 c = (*fcmp)(operand1, operand2);
9239 } else if (PyInstance_Check(operand2)) {
9240 cmpfunc fcmp = type2->tp_compare;
9241 c = (*fcmp)(operand1, operand2);
9242 } else {
9243 c = try_3way_compare(operand1, operand2);
9244 }
9245
9246 if (c >= 2) {
9247 if (&PyTuple_Type == type2) {
9248 Py_uintptr_t aa = (Py_uintptr_t)operand1;
9249 Py_uintptr_t bb = (Py_uintptr_t)operand2;
9250
9251 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9252 } else if (operand1 == Py_None) {
9253 // None is smaller than everything else
9254 c = -1;
9255 } else if (operand2 == Py_None) {
9256 // None is smaller than everything else
9257 c = 1;
9258 } else if (PyNumber_Check(operand1)) {
9259 // different type: compare type names but numbers are smaller than
9260 // others.
9261 if (PyNumber_Check(operand2)) {
9262 // Both numbers, need to make a decision based on types.
9263 Py_uintptr_t aa = (Py_uintptr_t)&PyTuple_Type;
9264 Py_uintptr_t bb = (Py_uintptr_t)type2;
9265
9266 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9267 } else {
9268 c = -1;
9269 }
9270 } else if (PyNumber_Check(operand2)) {
9271 c = 1;
9272 } else {
9273 // Banking on C compile to optimize "strcmp".
9274 int s = strcmp("tuple", type2->tp_name);
9275
9276 if (s < 0) {
9277 c = -1;
9278 } else if (s > 0) {
9279 c = 1;
9280 } else {
9281 // Same type name need to make a decision based on type address.
9282 Py_uintptr_t aa = (Py_uintptr_t)&PyTuple_Type;
9283 Py_uintptr_t bb = (Py_uintptr_t)type2;
9284
9285 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9286 }
9287 }
9288 }
9289
9290 Py_LeaveRecursiveCall();
9291
9292 if (unlikely(c <= -2)) {
9293 return NULL;
9294 }
9295
9296 switch (Py_GT) {
9297 case Py_LT:
9298 c = c < 0;
9299 break;
9300 case Py_LE:
9301 c = c <= 0;
9302 break;
9303 case Py_EQ:
9304 c = c == 0;
9305 break;
9306 case Py_NE:
9307 c = c != 0;
9308 break;
9309 case Py_GT:
9310 c = c > 0;
9311 break;
9312 case Py_GE:
9313 c = c >= 0;
9314 break;
9315 }
9316
9317 bool r = c != 0;
9318 PyObject *result = BOOL_FROM(r);
9319 Py_INCREF_IMMORTAL(result);
9320 return result;
9321#else
9322 bool checked_reverse_op = false;
9323 richcmpfunc f;
9324
9325 if (&PyTuple_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyTuple_Type)) {
9326 f = TP_RICHCOMPARE(type2);
9327
9328 if (f != NULL) {
9329 checked_reverse_op = true;
9330
9331 PyObject *result = (*f)(operand2, operand1, Py_LT);
9332
9333 if (result != Py_NotImplemented) {
9334 Py_LeaveRecursiveCall();
9335
9336 return result;
9337 }
9338
9339 Py_DECREF_IMMORTAL(result);
9340 }
9341 }
9342
9343 f = PyTuple_Type.tp_richcompare;
9344
9345 if (f != NULL) {
9346 PyObject *result = (*f)(operand1, operand2, Py_GT);
9347
9348 if (result != Py_NotImplemented) {
9349 Py_LeaveRecursiveCall();
9350
9351 return result;
9352 }
9353
9354 Py_DECREF_IMMORTAL(result);
9355 }
9356
9357 if (checked_reverse_op == false) {
9358 f = TP_RICHCOMPARE(type2);
9359
9360 if (f != NULL) {
9361 PyObject *result = (*f)(operand2, operand1, Py_LT);
9362
9363 if (result != Py_NotImplemented) {
9364 Py_LeaveRecursiveCall();
9365
9366 return result;
9367 }
9368
9369 Py_DECREF_IMMORTAL(result);
9370 }
9371 }
9372
9373 Py_LeaveRecursiveCall();
9374
9375 // If it is not implemented, do pointer identity checks as "==" and "!=" and
9376 // otherwise give an error
9377 switch (Py_GT) {
9378 case Py_EQ: {
9379 bool r = operand1 == operand2;
9380 PyObject *result = BOOL_FROM(r);
9381 Py_INCREF_IMMORTAL(result);
9382 return result;
9383 }
9384 case Py_NE: {
9385 bool r = operand1 != operand2;
9386 PyObject *result = BOOL_FROM(r);
9387 Py_INCREF_IMMORTAL(result);
9388 return result;
9389 }
9390 default:
9391#if PYTHON_VERSION < 0x360
9392 PyErr_Format(PyExc_TypeError, "unorderable types: tuple() > %s()", type2->tp_name);
9393#else
9394 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'tuple' and '%s'", type2->tp_name);
9395#endif
9396 return NULL;
9397 }
9398#endif
9399}
9400
9401/* Code referring to "TUPLE" corresponds to Python 'tuple' and "TUPLE" to Python 'tuple'. */
9402PyObject *RICH_COMPARE_GT_OBJECT_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
9403
9404 return COMPARE_GT_OBJECT_TUPLE_TUPLE(operand1, operand2);
9405}
9406
9407static nuitka_bool COMPARE_GT_NBOOL_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
9408 CHECK_OBJECT(operand1);
9409 assert(PyTuple_CheckExact(operand1));
9410 CHECK_OBJECT(operand2);
9411 assert(PyTuple_CheckExact(operand2));
9412
9413 PyTupleObject *a = (PyTupleObject *)operand1;
9414 PyTupleObject *b = (PyTupleObject *)operand2;
9415
9416 Py_ssize_t len_a = Py_SIZE(a);
9417 Py_ssize_t len_b = Py_SIZE(b);
9418
9419 bool found = false;
9420 nuitka_bool res = NUITKA_BOOL_TRUE;
9421
9422 Py_ssize_t i;
9423 for (i = 0; i < len_a && i < len_b; i++) {
9424 PyObject *aa = a->ob_item[i];
9425 PyObject *bb = b->ob_item[i];
9426
9427 if (aa == bb) {
9428 continue;
9429 }
9430
9431 res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(aa, bb);
9432
9433 if (res == NUITKA_BOOL_EXCEPTION) {
9434 return NUITKA_BOOL_EXCEPTION;
9435 }
9436
9437 if (res == NUITKA_BOOL_FALSE) {
9438 found = true;
9439 break;
9440 }
9441 }
9442
9443 if (found == false) {
9444 bool r = len_a > len_b;
9445
9446 // Convert to target type.
9447 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9448
9449 return result;
9450 }
9451
9452 return RICH_COMPARE_GT_NBOOL_OBJECT_OBJECT(a->ob_item[i], b->ob_item[i]);
9453}
9454/* Code referring to "OBJECT" corresponds to any Python object and "TUPLE" to Python 'tuple'. */
9455nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_TUPLE(PyObject *operand1, PyObject *operand2) {
9456
9457 if (Py_TYPE(operand1) == &PyTuple_Type) {
9458 return COMPARE_GT_NBOOL_TUPLE_TUPLE(operand1, operand2);
9459 }
9460
9461#if PYTHON_VERSION < 0x300
9462 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
9463 return NUITKA_BOOL_EXCEPTION;
9464 }
9465#else
9466 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
9467 return NUITKA_BOOL_EXCEPTION;
9468 }
9469#endif
9470
9471 PyTypeObject *type1 = Py_TYPE(operand1);
9472
9473#if PYTHON_VERSION < 0x300
9474 // If the types are equal, we may get away immediately except for instances.
9475 if (type1 == &PyTuple_Type && !0) {
9476
9477 richcmpfunc frich = PyTuple_Type.tp_richcompare;
9478
9479 if (frich != NULL) {
9480 PyObject *result = (*frich)(operand1, operand2, Py_GT);
9481
9482 if (result != Py_NotImplemented) {
9483 Py_LeaveRecursiveCall();
9484
9485 if (unlikely(result == NULL)) {
9486 return NUITKA_BOOL_EXCEPTION;
9487 }
9488
9489 {
9490 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9491 Py_DECREF(result);
9492 return r;
9493 }
9494 }
9495
9496 Py_DECREF_IMMORTAL(result);
9497 }
9498
9499 // No rich comparison worked, but maybe compare works.
9500 cmpfunc fcmp = NULL;
9501
9502 if (fcmp != NULL) {
9503 int c = (*fcmp)(operand1, operand2);
9504 c = adjust_tp_compare(c);
9505
9506 Py_LeaveRecursiveCall();
9507
9508 if (c == -2) {
9509 return NUITKA_BOOL_EXCEPTION;
9510 }
9511
9512 switch (Py_GT) {
9513 case Py_LT:
9514 c = c < 0;
9515 break;
9516 case Py_LE:
9517 c = c <= 0;
9518 break;
9519 case Py_EQ:
9520 c = c == 0;
9521 break;
9522 case Py_NE:
9523 c = c != 0;
9524 break;
9525 case Py_GT:
9526 c = c > 0;
9527 break;
9528 case Py_GE:
9529 c = c >= 0;
9530 break;
9531 default:
9532 NUITKA_CANNOT_GET_HERE("wrong op_code");
9533 }
9534
9535 bool r = c != 0;
9536 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9537
9538 return result;
9539 }
9540 }
9541
9542 // Fast path was not successful or not taken
9543 richcmpfunc f;
9544
9545 if (type1 != &PyTuple_Type && 0) {
9546 f = PyTuple_Type.tp_richcompare;
9547
9548 if (f != NULL) {
9549 PyObject *result = (*f)(operand2, operand1, Py_LT);
9550
9551 if (result != Py_NotImplemented) {
9552 Py_LeaveRecursiveCall();
9553
9554 if (unlikely(result == NULL)) {
9555 return NUITKA_BOOL_EXCEPTION;
9556 }
9557
9558 {
9559 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9560 Py_DECREF(result);
9561 return r;
9562 }
9563 }
9564
9565 Py_DECREF_IMMORTAL(result);
9566 }
9567 }
9568
9569 f = TP_RICHCOMPARE(type1);
9570 if (f != NULL) {
9571 PyObject *result = (*f)(operand1, operand2, Py_GT);
9572
9573 if (result != Py_NotImplemented) {
9574 Py_LeaveRecursiveCall();
9575
9576 if (unlikely(result == NULL)) {
9577 return NUITKA_BOOL_EXCEPTION;
9578 }
9579
9580 {
9581 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9582 Py_DECREF(result);
9583 return r;
9584 }
9585 }
9586
9587 Py_DECREF_IMMORTAL(result);
9588 }
9589
9590 f = PyTuple_Type.tp_richcompare;
9591 if (f != NULL) {
9592 PyObject *result = (*f)(operand2, operand1, Py_LT);
9593
9594 if (result != Py_NotImplemented) {
9595 Py_LeaveRecursiveCall();
9596
9597 if (unlikely(result == NULL)) {
9598 return NUITKA_BOOL_EXCEPTION;
9599 }
9600
9601 {
9602 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9603 Py_DECREF(result);
9604 return r;
9605 }
9606 }
9607
9608 Py_DECREF_IMMORTAL(result);
9609 }
9610
9611 int c;
9612
9613 if (PyInstance_Check(operand1)) {
9614 cmpfunc fcmp = type1->tp_compare;
9615 c = (*fcmp)(operand1, operand2);
9616 } else if (0) {
9617 cmpfunc fcmp = NULL;
9618 c = (*fcmp)(operand1, operand2);
9619 } else {
9620 c = try_3way_compare(operand1, operand2);
9621 }
9622
9623 if (c >= 2) {
9624 if (type1 == &PyTuple_Type) {
9625 Py_uintptr_t aa = (Py_uintptr_t)operand1;
9626 Py_uintptr_t bb = (Py_uintptr_t)operand2;
9627
9628 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9629 } else if (operand1 == Py_None) {
9630 // None is smaller than everything else
9631 c = -1;
9632 } else if (operand2 == Py_None) {
9633 // None is smaller than everything else
9634 c = 1;
9635 } else if (PyNumber_Check(operand1)) {
9636 // different type: compare type names but numbers are smaller than
9637 // others.
9638 if (PyNumber_Check(operand2)) {
9639 // Both numbers, need to make a decision based on types.
9640 Py_uintptr_t aa = (Py_uintptr_t)type1;
9641 Py_uintptr_t bb = (Py_uintptr_t)&PyTuple_Type;
9642
9643 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9644 } else {
9645 c = -1;
9646 }
9647 } else if (PyNumber_Check(operand2)) {
9648 c = 1;
9649 } else {
9650 // Banking on C compile to optimize "strcmp".
9651 int s = strcmp(type1->tp_name, "tuple");
9652
9653 if (s < 0) {
9654 c = -1;
9655 } else if (s > 0) {
9656 c = 1;
9657 } else {
9658 // Same type name need to make a decision based on type address.
9659 Py_uintptr_t aa = (Py_uintptr_t)type1;
9660 Py_uintptr_t bb = (Py_uintptr_t)&PyTuple_Type;
9661
9662 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9663 }
9664 }
9665 }
9666
9667 Py_LeaveRecursiveCall();
9668
9669 if (unlikely(c <= -2)) {
9670 return NUITKA_BOOL_EXCEPTION;
9671 }
9672
9673 switch (Py_GT) {
9674 case Py_LT:
9675 c = c < 0;
9676 break;
9677 case Py_LE:
9678 c = c <= 0;
9679 break;
9680 case Py_EQ:
9681 c = c == 0;
9682 break;
9683 case Py_NE:
9684 c = c != 0;
9685 break;
9686 case Py_GT:
9687 c = c > 0;
9688 break;
9689 case Py_GE:
9690 c = c >= 0;
9691 break;
9692 }
9693
9694 bool r = c != 0;
9695 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9696
9697 return result;
9698#else
9699 bool checked_reverse_op = false;
9700 richcmpfunc f;
9701
9702 if (type1 != &PyTuple_Type && Nuitka_Type_IsSubtype(&PyTuple_Type, type1)) {
9703 f = PyTuple_Type.tp_richcompare;
9704
9705 if (f != NULL) {
9706 checked_reverse_op = true;
9707
9708 PyObject *result = (*f)(operand2, operand1, Py_LT);
9709
9710 if (result != Py_NotImplemented) {
9711 Py_LeaveRecursiveCall();
9712
9713 if (unlikely(result == NULL)) {
9714 return NUITKA_BOOL_EXCEPTION;
9715 }
9716
9717 {
9718 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9719 Py_DECREF(result);
9720 return r;
9721 }
9722 }
9723
9724 Py_DECREF_IMMORTAL(result);
9725 }
9726 }
9727
9728 f = TP_RICHCOMPARE(type1);
9729
9730 if (f != NULL) {
9731 PyObject *result = (*f)(operand1, operand2, Py_GT);
9732
9733 if (result != Py_NotImplemented) {
9734 Py_LeaveRecursiveCall();
9735
9736 if (unlikely(result == NULL)) {
9737 return NUITKA_BOOL_EXCEPTION;
9738 }
9739
9740 {
9741 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9742 Py_DECREF(result);
9743 return r;
9744 }
9745 }
9746
9747 Py_DECREF_IMMORTAL(result);
9748 }
9749
9750 if (checked_reverse_op == false) {
9751 f = PyTuple_Type.tp_richcompare;
9752
9753 if (f != NULL) {
9754 PyObject *result = (*f)(operand2, operand1, Py_LT);
9755
9756 if (result != Py_NotImplemented) {
9757 Py_LeaveRecursiveCall();
9758
9759 if (unlikely(result == NULL)) {
9760 return NUITKA_BOOL_EXCEPTION;
9761 }
9762
9763 {
9764 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9765 Py_DECREF(result);
9766 return r;
9767 }
9768 }
9769
9770 Py_DECREF_IMMORTAL(result);
9771 }
9772 }
9773
9774 Py_LeaveRecursiveCall();
9775
9776 // If it is not implemented, do pointer identity checks as "==" and "!=" and
9777 // otherwise give an error
9778 switch (Py_GT) {
9779 case Py_EQ: {
9780 bool r = operand1 == operand2;
9781 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9782
9783 return result;
9784 }
9785 case Py_NE: {
9786 bool r = operand1 != operand2;
9787 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9788
9789 return result;
9790 }
9791 default:
9792#if PYTHON_VERSION < 0x360
9793 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > tuple()", type1->tp_name);
9794#else
9795 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'tuple'", type1->tp_name);
9796#endif
9797 return NUITKA_BOOL_EXCEPTION;
9798 }
9799#endif
9800}
9801
9802/* Code referring to "TUPLE" corresponds to Python 'tuple' and "OBJECT" to any Python object. */
9803nuitka_bool RICH_COMPARE_GT_NBOOL_TUPLE_OBJECT(PyObject *operand1, PyObject *operand2) {
9804
9805 if (&PyTuple_Type == Py_TYPE(operand2)) {
9806 return COMPARE_GT_NBOOL_TUPLE_TUPLE(operand1, operand2);
9807 }
9808
9809#if PYTHON_VERSION < 0x300
9810 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
9811 return NUITKA_BOOL_EXCEPTION;
9812 }
9813#else
9814 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
9815 return NUITKA_BOOL_EXCEPTION;
9816 }
9817#endif
9818
9819 PyTypeObject *type2 = Py_TYPE(operand2);
9820
9821#if PYTHON_VERSION < 0x300
9822 // If the types are equal, we may get away immediately except for instances.
9823 if (&PyTuple_Type == type2 && !0) {
9824
9825 richcmpfunc frich = PyTuple_Type.tp_richcompare;
9826
9827 if (frich != NULL) {
9828 PyObject *result = (*frich)(operand1, operand2, Py_GT);
9829
9830 if (result != Py_NotImplemented) {
9831 Py_LeaveRecursiveCall();
9832
9833 if (unlikely(result == NULL)) {
9834 return NUITKA_BOOL_EXCEPTION;
9835 }
9836
9837 {
9838 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9839 Py_DECREF(result);
9840 return r;
9841 }
9842 }
9843
9844 Py_DECREF_IMMORTAL(result);
9845 }
9846
9847 // No rich comparison worked, but maybe compare works.
9848 cmpfunc fcmp = NULL;
9849
9850 if (fcmp != NULL) {
9851 int c = (*fcmp)(operand1, operand2);
9852 c = adjust_tp_compare(c);
9853
9854 Py_LeaveRecursiveCall();
9855
9856 if (c == -2) {
9857 return NUITKA_BOOL_EXCEPTION;
9858 }
9859
9860 switch (Py_GT) {
9861 case Py_LT:
9862 c = c < 0;
9863 break;
9864 case Py_LE:
9865 c = c <= 0;
9866 break;
9867 case Py_EQ:
9868 c = c == 0;
9869 break;
9870 case Py_NE:
9871 c = c != 0;
9872 break;
9873 case Py_GT:
9874 c = c > 0;
9875 break;
9876 case Py_GE:
9877 c = c >= 0;
9878 break;
9879 default:
9880 NUITKA_CANNOT_GET_HERE("wrong op_code");
9881 }
9882
9883 bool r = c != 0;
9884 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9885
9886 return result;
9887 }
9888 }
9889
9890 // Fast path was not successful or not taken
9891 richcmpfunc f;
9892
9893 if (&PyTuple_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyTuple_Type)) {
9894 f = TP_RICHCOMPARE(type2);
9895
9896 if (f != NULL) {
9897 PyObject *result = (*f)(operand2, operand1, Py_LT);
9898
9899 if (result != Py_NotImplemented) {
9900 Py_LeaveRecursiveCall();
9901
9902 if (unlikely(result == NULL)) {
9903 return NUITKA_BOOL_EXCEPTION;
9904 }
9905
9906 {
9907 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9908 Py_DECREF(result);
9909 return r;
9910 }
9911 }
9912
9913 Py_DECREF_IMMORTAL(result);
9914 }
9915 }
9916
9917 f = PyTuple_Type.tp_richcompare;
9918 if (f != NULL) {
9919 PyObject *result = (*f)(operand1, operand2, Py_GT);
9920
9921 if (result != Py_NotImplemented) {
9922 Py_LeaveRecursiveCall();
9923
9924 if (unlikely(result == NULL)) {
9925 return NUITKA_BOOL_EXCEPTION;
9926 }
9927
9928 {
9929 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9930 Py_DECREF(result);
9931 return r;
9932 }
9933 }
9934
9935 Py_DECREF_IMMORTAL(result);
9936 }
9937
9938 f = TP_RICHCOMPARE(type2);
9939 if (f != NULL) {
9940 PyObject *result = (*f)(operand2, operand1, Py_LT);
9941
9942 if (result != Py_NotImplemented) {
9943 Py_LeaveRecursiveCall();
9944
9945 if (unlikely(result == NULL)) {
9946 return NUITKA_BOOL_EXCEPTION;
9947 }
9948
9949 {
9950 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
9951 Py_DECREF(result);
9952 return r;
9953 }
9954 }
9955
9956 Py_DECREF_IMMORTAL(result);
9957 }
9958
9959 int c;
9960
9961 if (0) {
9962 cmpfunc fcmp = NULL;
9963 c = (*fcmp)(operand1, operand2);
9964 } else if (PyInstance_Check(operand2)) {
9965 cmpfunc fcmp = type2->tp_compare;
9966 c = (*fcmp)(operand1, operand2);
9967 } else {
9968 c = try_3way_compare(operand1, operand2);
9969 }
9970
9971 if (c >= 2) {
9972 if (&PyTuple_Type == type2) {
9973 Py_uintptr_t aa = (Py_uintptr_t)operand1;
9974 Py_uintptr_t bb = (Py_uintptr_t)operand2;
9975
9976 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9977 } else if (operand1 == Py_None) {
9978 // None is smaller than everything else
9979 c = -1;
9980 } else if (operand2 == Py_None) {
9981 // None is smaller than everything else
9982 c = 1;
9983 } else if (PyNumber_Check(operand1)) {
9984 // different type: compare type names but numbers are smaller than
9985 // others.
9986 if (PyNumber_Check(operand2)) {
9987 // Both numbers, need to make a decision based on types.
9988 Py_uintptr_t aa = (Py_uintptr_t)&PyTuple_Type;
9989 Py_uintptr_t bb = (Py_uintptr_t)type2;
9990
9991 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
9992 } else {
9993 c = -1;
9994 }
9995 } else if (PyNumber_Check(operand2)) {
9996 c = 1;
9997 } else {
9998 // Banking on C compile to optimize "strcmp".
9999 int s = strcmp("tuple", type2->tp_name);
10000
10001 if (s < 0) {
10002 c = -1;
10003 } else if (s > 0) {
10004 c = 1;
10005 } else {
10006 // Same type name need to make a decision based on type address.
10007 Py_uintptr_t aa = (Py_uintptr_t)&PyTuple_Type;
10008 Py_uintptr_t bb = (Py_uintptr_t)type2;
10009
10010 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10011 }
10012 }
10013 }
10014
10015 Py_LeaveRecursiveCall();
10016
10017 if (unlikely(c <= -2)) {
10018 return NUITKA_BOOL_EXCEPTION;
10019 }
10020
10021 switch (Py_GT) {
10022 case Py_LT:
10023 c = c < 0;
10024 break;
10025 case Py_LE:
10026 c = c <= 0;
10027 break;
10028 case Py_EQ:
10029 c = c == 0;
10030 break;
10031 case Py_NE:
10032 c = c != 0;
10033 break;
10034 case Py_GT:
10035 c = c > 0;
10036 break;
10037 case Py_GE:
10038 c = c >= 0;
10039 break;
10040 }
10041
10042 bool r = c != 0;
10043 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10044
10045 return result;
10046#else
10047 bool checked_reverse_op = false;
10048 richcmpfunc f;
10049
10050 if (&PyTuple_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyTuple_Type)) {
10051 f = TP_RICHCOMPARE(type2);
10052
10053 if (f != NULL) {
10054 checked_reverse_op = true;
10055
10056 PyObject *result = (*f)(operand2, operand1, Py_LT);
10057
10058 if (result != Py_NotImplemented) {
10059 Py_LeaveRecursiveCall();
10060
10061 if (unlikely(result == NULL)) {
10062 return NUITKA_BOOL_EXCEPTION;
10063 }
10064
10065 {
10066 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10067 Py_DECREF(result);
10068 return r;
10069 }
10070 }
10071
10072 Py_DECREF_IMMORTAL(result);
10073 }
10074 }
10075
10076 f = PyTuple_Type.tp_richcompare;
10077
10078 if (f != NULL) {
10079 PyObject *result = (*f)(operand1, operand2, Py_GT);
10080
10081 if (result != Py_NotImplemented) {
10082 Py_LeaveRecursiveCall();
10083
10084 if (unlikely(result == NULL)) {
10085 return NUITKA_BOOL_EXCEPTION;
10086 }
10087
10088 {
10089 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10090 Py_DECREF(result);
10091 return r;
10092 }
10093 }
10094
10095 Py_DECREF_IMMORTAL(result);
10096 }
10097
10098 if (checked_reverse_op == false) {
10099 f = TP_RICHCOMPARE(type2);
10100
10101 if (f != NULL) {
10102 PyObject *result = (*f)(operand2, operand1, Py_LT);
10103
10104 if (result != Py_NotImplemented) {
10105 Py_LeaveRecursiveCall();
10106
10107 if (unlikely(result == NULL)) {
10108 return NUITKA_BOOL_EXCEPTION;
10109 }
10110
10111 {
10112 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10113 Py_DECREF(result);
10114 return r;
10115 }
10116 }
10117
10118 Py_DECREF_IMMORTAL(result);
10119 }
10120 }
10121
10122 Py_LeaveRecursiveCall();
10123
10124 // If it is not implemented, do pointer identity checks as "==" and "!=" and
10125 // otherwise give an error
10126 switch (Py_GT) {
10127 case Py_EQ: {
10128 bool r = operand1 == operand2;
10129 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10130
10131 return result;
10132 }
10133 case Py_NE: {
10134 bool r = operand1 != operand2;
10135 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10136
10137 return result;
10138 }
10139 default:
10140#if PYTHON_VERSION < 0x360
10141 PyErr_Format(PyExc_TypeError, "unorderable types: tuple() > %s()", type2->tp_name);
10142#else
10143 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'tuple' and '%s'", type2->tp_name);
10144#endif
10145 return NUITKA_BOOL_EXCEPTION;
10146 }
10147#endif
10148}
10149
10150/* Code referring to "TUPLE" corresponds to Python 'tuple' and "TUPLE" to Python 'tuple'. */
10151nuitka_bool RICH_COMPARE_GT_NBOOL_TUPLE_TUPLE(PyObject *operand1, PyObject *operand2) {
10152
10153 return COMPARE_GT_NBOOL_TUPLE_TUPLE(operand1, operand2);
10154}
10155
10156static PyObject *COMPARE_GT_OBJECT_LIST_LIST(PyObject *operand1, PyObject *operand2) {
10157 CHECK_OBJECT(operand1);
10158 assert(PyList_CheckExact(operand1));
10159 CHECK_OBJECT(operand2);
10160 assert(PyList_CheckExact(operand2));
10161
10162 PyListObject *a = (PyListObject *)operand1;
10163 PyListObject *b = (PyListObject *)operand2;
10164
10165 bool found = false;
10166 nuitka_bool res = NUITKA_BOOL_TRUE;
10167
10168 Py_ssize_t i;
10169 for (i = 0; i < Py_SIZE(a) && i < Py_SIZE(b); i++) {
10170 PyObject *aa = a->ob_item[i];
10171 PyObject *bb = b->ob_item[i];
10172
10173 if (aa == bb) {
10174 continue;
10175 }
10176
10177 Py_INCREF(aa);
10178 Py_INCREF(bb);
10179 res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(aa, bb);
10180 Py_DECREF(aa);
10181 Py_DECREF(bb);
10182
10183 if (res == NUITKA_BOOL_EXCEPTION) {
10184 return NULL;
10185 }
10186
10187 if (res == NUITKA_BOOL_FALSE) {
10188 found = true;
10189 break;
10190 }
10191 }
10192
10193 if (found == false) {
10194 bool r = Py_SIZE(a) > Py_SIZE(b);
10195
10196 // Convert to target type.
10197 PyObject *result = BOOL_FROM(r);
10198 Py_INCREF_IMMORTAL(result);
10199 return result;
10200 }
10201
10202 return RICH_COMPARE_GT_OBJECT_OBJECT_OBJECT(a->ob_item[i], b->ob_item[i]);
10203}
10204/* Code referring to "OBJECT" corresponds to any Python object and "LIST" to Python 'list'. */
10205PyObject *RICH_COMPARE_GT_OBJECT_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
10206
10207 if (Py_TYPE(operand1) == &PyList_Type) {
10208 return COMPARE_GT_OBJECT_LIST_LIST(operand1, operand2);
10209 }
10210
10211#if PYTHON_VERSION < 0x300
10212 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
10213 return NULL;
10214 }
10215#else
10216 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
10217 return NULL;
10218 }
10219#endif
10220
10221 PyTypeObject *type1 = Py_TYPE(operand1);
10222
10223#if PYTHON_VERSION < 0x300
10224 // If the types are equal, we may get away immediately except for instances.
10225 if (type1 == &PyList_Type && !0) {
10226
10227 richcmpfunc frich = PyList_Type.tp_richcompare;
10228
10229 if (frich != NULL) {
10230 PyObject *result = (*frich)(operand1, operand2, Py_GT);
10231
10232 if (result != Py_NotImplemented) {
10233 Py_LeaveRecursiveCall();
10234
10235 return result;
10236 }
10237
10238 Py_DECREF_IMMORTAL(result);
10239 }
10240
10241 // No rich comparison worked, but maybe compare works.
10242 cmpfunc fcmp = NULL;
10243
10244 if (fcmp != NULL) {
10245 int c = (*fcmp)(operand1, operand2);
10246 c = adjust_tp_compare(c);
10247
10248 Py_LeaveRecursiveCall();
10249
10250 if (c == -2) {
10251 return NULL;
10252 }
10253
10254 switch (Py_GT) {
10255 case Py_LT:
10256 c = c < 0;
10257 break;
10258 case Py_LE:
10259 c = c <= 0;
10260 break;
10261 case Py_EQ:
10262 c = c == 0;
10263 break;
10264 case Py_NE:
10265 c = c != 0;
10266 break;
10267 case Py_GT:
10268 c = c > 0;
10269 break;
10270 case Py_GE:
10271 c = c >= 0;
10272 break;
10273 default:
10274 NUITKA_CANNOT_GET_HERE("wrong op_code");
10275 }
10276
10277 bool r = c != 0;
10278 PyObject *result = BOOL_FROM(r);
10279 Py_INCREF_IMMORTAL(result);
10280 return result;
10281 }
10282 }
10283
10284 // Fast path was not successful or not taken
10285 richcmpfunc f;
10286
10287 if (type1 != &PyList_Type && 0) {
10288 f = PyList_Type.tp_richcompare;
10289
10290 if (f != NULL) {
10291 PyObject *result = (*f)(operand2, operand1, Py_LT);
10292
10293 if (result != Py_NotImplemented) {
10294 Py_LeaveRecursiveCall();
10295
10296 return result;
10297 }
10298
10299 Py_DECREF_IMMORTAL(result);
10300 }
10301 }
10302
10303 f = TP_RICHCOMPARE(type1);
10304 if (f != NULL) {
10305 PyObject *result = (*f)(operand1, operand2, Py_GT);
10306
10307 if (result != Py_NotImplemented) {
10308 Py_LeaveRecursiveCall();
10309
10310 return result;
10311 }
10312
10313 Py_DECREF_IMMORTAL(result);
10314 }
10315
10316 f = PyList_Type.tp_richcompare;
10317 if (f != NULL) {
10318 PyObject *result = (*f)(operand2, operand1, Py_LT);
10319
10320 if (result != Py_NotImplemented) {
10321 Py_LeaveRecursiveCall();
10322
10323 return result;
10324 }
10325
10326 Py_DECREF_IMMORTAL(result);
10327 }
10328
10329 int c;
10330
10331 if (PyInstance_Check(operand1)) {
10332 cmpfunc fcmp = type1->tp_compare;
10333 c = (*fcmp)(operand1, operand2);
10334 } else if (0) {
10335 cmpfunc fcmp = NULL;
10336 c = (*fcmp)(operand1, operand2);
10337 } else {
10338 c = try_3way_compare(operand1, operand2);
10339 }
10340
10341 if (c >= 2) {
10342 if (type1 == &PyList_Type) {
10343 Py_uintptr_t aa = (Py_uintptr_t)operand1;
10344 Py_uintptr_t bb = (Py_uintptr_t)operand2;
10345
10346 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10347 } else if (operand1 == Py_None) {
10348 // None is smaller than everything else
10349 c = -1;
10350 } else if (operand2 == Py_None) {
10351 // None is smaller than everything else
10352 c = 1;
10353 } else if (PyNumber_Check(operand1)) {
10354 // different type: compare type names but numbers are smaller than
10355 // others.
10356 if (PyNumber_Check(operand2)) {
10357 // Both numbers, need to make a decision based on types.
10358 Py_uintptr_t aa = (Py_uintptr_t)type1;
10359 Py_uintptr_t bb = (Py_uintptr_t)&PyList_Type;
10360
10361 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10362 } else {
10363 c = -1;
10364 }
10365 } else if (PyNumber_Check(operand2)) {
10366 c = 1;
10367 } else {
10368 // Banking on C compile to optimize "strcmp".
10369 int s = strcmp(type1->tp_name, "list");
10370
10371 if (s < 0) {
10372 c = -1;
10373 } else if (s > 0) {
10374 c = 1;
10375 } else {
10376 // Same type name need to make a decision based on type address.
10377 Py_uintptr_t aa = (Py_uintptr_t)type1;
10378 Py_uintptr_t bb = (Py_uintptr_t)&PyList_Type;
10379
10380 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10381 }
10382 }
10383 }
10384
10385 Py_LeaveRecursiveCall();
10386
10387 if (unlikely(c <= -2)) {
10388 return NULL;
10389 }
10390
10391 switch (Py_GT) {
10392 case Py_LT:
10393 c = c < 0;
10394 break;
10395 case Py_LE:
10396 c = c <= 0;
10397 break;
10398 case Py_EQ:
10399 c = c == 0;
10400 break;
10401 case Py_NE:
10402 c = c != 0;
10403 break;
10404 case Py_GT:
10405 c = c > 0;
10406 break;
10407 case Py_GE:
10408 c = c >= 0;
10409 break;
10410 }
10411
10412 bool r = c != 0;
10413 PyObject *result = BOOL_FROM(r);
10414 Py_INCREF_IMMORTAL(result);
10415 return result;
10416#else
10417 bool checked_reverse_op = false;
10418 richcmpfunc f;
10419
10420 if (type1 != &PyList_Type && Nuitka_Type_IsSubtype(&PyList_Type, type1)) {
10421 f = PyList_Type.tp_richcompare;
10422
10423 if (f != NULL) {
10424 checked_reverse_op = true;
10425
10426 PyObject *result = (*f)(operand2, operand1, Py_LT);
10427
10428 if (result != Py_NotImplemented) {
10429 Py_LeaveRecursiveCall();
10430
10431 return result;
10432 }
10433
10434 Py_DECREF_IMMORTAL(result);
10435 }
10436 }
10437
10438 f = TP_RICHCOMPARE(type1);
10439
10440 if (f != NULL) {
10441 PyObject *result = (*f)(operand1, operand2, Py_GT);
10442
10443 if (result != Py_NotImplemented) {
10444 Py_LeaveRecursiveCall();
10445
10446 return result;
10447 }
10448
10449 Py_DECREF_IMMORTAL(result);
10450 }
10451
10452 if (checked_reverse_op == false) {
10453 f = PyList_Type.tp_richcompare;
10454
10455 if (f != NULL) {
10456 PyObject *result = (*f)(operand2, operand1, Py_LT);
10457
10458 if (result != Py_NotImplemented) {
10459 Py_LeaveRecursiveCall();
10460
10461 return result;
10462 }
10463
10464 Py_DECREF_IMMORTAL(result);
10465 }
10466 }
10467
10468 Py_LeaveRecursiveCall();
10469
10470 // If it is not implemented, do pointer identity checks as "==" and "!=" and
10471 // otherwise give an error
10472 switch (Py_GT) {
10473 case Py_EQ: {
10474 bool r = operand1 == operand2;
10475 PyObject *result = BOOL_FROM(r);
10476 Py_INCREF_IMMORTAL(result);
10477 return result;
10478 }
10479 case Py_NE: {
10480 bool r = operand1 != operand2;
10481 PyObject *result = BOOL_FROM(r);
10482 Py_INCREF_IMMORTAL(result);
10483 return result;
10484 }
10485 default:
10486#if PYTHON_VERSION < 0x360
10487 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > list()", type1->tp_name);
10488#else
10489 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'list'", type1->tp_name);
10490#endif
10491 return NULL;
10492 }
10493#endif
10494}
10495
10496/* Code referring to "LIST" corresponds to Python 'list' and "OBJECT" to any Python object. */
10497PyObject *RICH_COMPARE_GT_OBJECT_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
10498
10499 if (&PyList_Type == Py_TYPE(operand2)) {
10500 return COMPARE_GT_OBJECT_LIST_LIST(operand1, operand2);
10501 }
10502
10503#if PYTHON_VERSION < 0x300
10504 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
10505 return NULL;
10506 }
10507#else
10508 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
10509 return NULL;
10510 }
10511#endif
10512
10513 PyTypeObject *type2 = Py_TYPE(operand2);
10514
10515#if PYTHON_VERSION < 0x300
10516 // If the types are equal, we may get away immediately except for instances.
10517 if (&PyList_Type == type2 && !0) {
10518
10519 richcmpfunc frich = PyList_Type.tp_richcompare;
10520
10521 if (frich != NULL) {
10522 PyObject *result = (*frich)(operand1, operand2, Py_GT);
10523
10524 if (result != Py_NotImplemented) {
10525 Py_LeaveRecursiveCall();
10526
10527 return result;
10528 }
10529
10530 Py_DECREF_IMMORTAL(result);
10531 }
10532
10533 // No rich comparison worked, but maybe compare works.
10534 cmpfunc fcmp = NULL;
10535
10536 if (fcmp != NULL) {
10537 int c = (*fcmp)(operand1, operand2);
10538 c = adjust_tp_compare(c);
10539
10540 Py_LeaveRecursiveCall();
10541
10542 if (c == -2) {
10543 return NULL;
10544 }
10545
10546 switch (Py_GT) {
10547 case Py_LT:
10548 c = c < 0;
10549 break;
10550 case Py_LE:
10551 c = c <= 0;
10552 break;
10553 case Py_EQ:
10554 c = c == 0;
10555 break;
10556 case Py_NE:
10557 c = c != 0;
10558 break;
10559 case Py_GT:
10560 c = c > 0;
10561 break;
10562 case Py_GE:
10563 c = c >= 0;
10564 break;
10565 default:
10566 NUITKA_CANNOT_GET_HERE("wrong op_code");
10567 }
10568
10569 bool r = c != 0;
10570 PyObject *result = BOOL_FROM(r);
10571 Py_INCREF_IMMORTAL(result);
10572 return result;
10573 }
10574 }
10575
10576 // Fast path was not successful or not taken
10577 richcmpfunc f;
10578
10579 if (&PyList_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyList_Type)) {
10580 f = TP_RICHCOMPARE(type2);
10581
10582 if (f != NULL) {
10583 PyObject *result = (*f)(operand2, operand1, Py_LT);
10584
10585 if (result != Py_NotImplemented) {
10586 Py_LeaveRecursiveCall();
10587
10588 return result;
10589 }
10590
10591 Py_DECREF_IMMORTAL(result);
10592 }
10593 }
10594
10595 f = PyList_Type.tp_richcompare;
10596 if (f != NULL) {
10597 PyObject *result = (*f)(operand1, operand2, Py_GT);
10598
10599 if (result != Py_NotImplemented) {
10600 Py_LeaveRecursiveCall();
10601
10602 return result;
10603 }
10604
10605 Py_DECREF_IMMORTAL(result);
10606 }
10607
10608 f = TP_RICHCOMPARE(type2);
10609 if (f != NULL) {
10610 PyObject *result = (*f)(operand2, operand1, Py_LT);
10611
10612 if (result != Py_NotImplemented) {
10613 Py_LeaveRecursiveCall();
10614
10615 return result;
10616 }
10617
10618 Py_DECREF_IMMORTAL(result);
10619 }
10620
10621 int c;
10622
10623 if (0) {
10624 cmpfunc fcmp = NULL;
10625 c = (*fcmp)(operand1, operand2);
10626 } else if (PyInstance_Check(operand2)) {
10627 cmpfunc fcmp = type2->tp_compare;
10628 c = (*fcmp)(operand1, operand2);
10629 } else {
10630 c = try_3way_compare(operand1, operand2);
10631 }
10632
10633 if (c >= 2) {
10634 if (&PyList_Type == type2) {
10635 Py_uintptr_t aa = (Py_uintptr_t)operand1;
10636 Py_uintptr_t bb = (Py_uintptr_t)operand2;
10637
10638 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10639 } else if (operand1 == Py_None) {
10640 // None is smaller than everything else
10641 c = -1;
10642 } else if (operand2 == Py_None) {
10643 // None is smaller than everything else
10644 c = 1;
10645 } else if (PyNumber_Check(operand1)) {
10646 // different type: compare type names but numbers are smaller than
10647 // others.
10648 if (PyNumber_Check(operand2)) {
10649 // Both numbers, need to make a decision based on types.
10650 Py_uintptr_t aa = (Py_uintptr_t)&PyList_Type;
10651 Py_uintptr_t bb = (Py_uintptr_t)type2;
10652
10653 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10654 } else {
10655 c = -1;
10656 }
10657 } else if (PyNumber_Check(operand2)) {
10658 c = 1;
10659 } else {
10660 // Banking on C compile to optimize "strcmp".
10661 int s = strcmp("list", type2->tp_name);
10662
10663 if (s < 0) {
10664 c = -1;
10665 } else if (s > 0) {
10666 c = 1;
10667 } else {
10668 // Same type name need to make a decision based on type address.
10669 Py_uintptr_t aa = (Py_uintptr_t)&PyList_Type;
10670 Py_uintptr_t bb = (Py_uintptr_t)type2;
10671
10672 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
10673 }
10674 }
10675 }
10676
10677 Py_LeaveRecursiveCall();
10678
10679 if (unlikely(c <= -2)) {
10680 return NULL;
10681 }
10682
10683 switch (Py_GT) {
10684 case Py_LT:
10685 c = c < 0;
10686 break;
10687 case Py_LE:
10688 c = c <= 0;
10689 break;
10690 case Py_EQ:
10691 c = c == 0;
10692 break;
10693 case Py_NE:
10694 c = c != 0;
10695 break;
10696 case Py_GT:
10697 c = c > 0;
10698 break;
10699 case Py_GE:
10700 c = c >= 0;
10701 break;
10702 }
10703
10704 bool r = c != 0;
10705 PyObject *result = BOOL_FROM(r);
10706 Py_INCREF_IMMORTAL(result);
10707 return result;
10708#else
10709 bool checked_reverse_op = false;
10710 richcmpfunc f;
10711
10712 if (&PyList_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyList_Type)) {
10713 f = TP_RICHCOMPARE(type2);
10714
10715 if (f != NULL) {
10716 checked_reverse_op = true;
10717
10718 PyObject *result = (*f)(operand2, operand1, Py_LT);
10719
10720 if (result != Py_NotImplemented) {
10721 Py_LeaveRecursiveCall();
10722
10723 return result;
10724 }
10725
10726 Py_DECREF_IMMORTAL(result);
10727 }
10728 }
10729
10730 f = PyList_Type.tp_richcompare;
10731
10732 if (f != NULL) {
10733 PyObject *result = (*f)(operand1, operand2, Py_GT);
10734
10735 if (result != Py_NotImplemented) {
10736 Py_LeaveRecursiveCall();
10737
10738 return result;
10739 }
10740
10741 Py_DECREF_IMMORTAL(result);
10742 }
10743
10744 if (checked_reverse_op == false) {
10745 f = TP_RICHCOMPARE(type2);
10746
10747 if (f != NULL) {
10748 PyObject *result = (*f)(operand2, operand1, Py_LT);
10749
10750 if (result != Py_NotImplemented) {
10751 Py_LeaveRecursiveCall();
10752
10753 return result;
10754 }
10755
10756 Py_DECREF_IMMORTAL(result);
10757 }
10758 }
10759
10760 Py_LeaveRecursiveCall();
10761
10762 // If it is not implemented, do pointer identity checks as "==" and "!=" and
10763 // otherwise give an error
10764 switch (Py_GT) {
10765 case Py_EQ: {
10766 bool r = operand1 == operand2;
10767 PyObject *result = BOOL_FROM(r);
10768 Py_INCREF_IMMORTAL(result);
10769 return result;
10770 }
10771 case Py_NE: {
10772 bool r = operand1 != operand2;
10773 PyObject *result = BOOL_FROM(r);
10774 Py_INCREF_IMMORTAL(result);
10775 return result;
10776 }
10777 default:
10778#if PYTHON_VERSION < 0x360
10779 PyErr_Format(PyExc_TypeError, "unorderable types: list() > %s()", type2->tp_name);
10780#else
10781 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'list' and '%s'", type2->tp_name);
10782#endif
10783 return NULL;
10784 }
10785#endif
10786}
10787
10788/* Code referring to "LIST" corresponds to Python 'list' and "LIST" to Python 'list'. */
10789PyObject *RICH_COMPARE_GT_OBJECT_LIST_LIST(PyObject *operand1, PyObject *operand2) {
10790
10791 return COMPARE_GT_OBJECT_LIST_LIST(operand1, operand2);
10792}
10793
10794static nuitka_bool COMPARE_GT_NBOOL_LIST_LIST(PyObject *operand1, PyObject *operand2) {
10795 CHECK_OBJECT(operand1);
10796 assert(PyList_CheckExact(operand1));
10797 CHECK_OBJECT(operand2);
10798 assert(PyList_CheckExact(operand2));
10799
10800 PyListObject *a = (PyListObject *)operand1;
10801 PyListObject *b = (PyListObject *)operand2;
10802
10803 bool found = false;
10804 nuitka_bool res = NUITKA_BOOL_TRUE;
10805
10806 Py_ssize_t i;
10807 for (i = 0; i < Py_SIZE(a) && i < Py_SIZE(b); i++) {
10808 PyObject *aa = a->ob_item[i];
10809 PyObject *bb = b->ob_item[i];
10810
10811 if (aa == bb) {
10812 continue;
10813 }
10814
10815 Py_INCREF(aa);
10816 Py_INCREF(bb);
10817 res = RICH_COMPARE_EQ_NBOOL_OBJECT_OBJECT(aa, bb);
10818 Py_DECREF(aa);
10819 Py_DECREF(bb);
10820
10821 if (res == NUITKA_BOOL_EXCEPTION) {
10822 return NUITKA_BOOL_EXCEPTION;
10823 }
10824
10825 if (res == NUITKA_BOOL_FALSE) {
10826 found = true;
10827 break;
10828 }
10829 }
10830
10831 if (found == false) {
10832 bool r = Py_SIZE(a) > Py_SIZE(b);
10833
10834 // Convert to target type.
10835 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10836
10837 return result;
10838 }
10839
10840 return RICH_COMPARE_GT_NBOOL_OBJECT_OBJECT(a->ob_item[i], b->ob_item[i]);
10841}
10842/* Code referring to "OBJECT" corresponds to any Python object and "LIST" to Python 'list'. */
10843nuitka_bool RICH_COMPARE_GT_NBOOL_OBJECT_LIST(PyObject *operand1, PyObject *operand2) {
10844
10845 if (Py_TYPE(operand1) == &PyList_Type) {
10846 return COMPARE_GT_NBOOL_LIST_LIST(operand1, operand2);
10847 }
10848
10849#if PYTHON_VERSION < 0x300
10850 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
10851 return NUITKA_BOOL_EXCEPTION;
10852 }
10853#else
10854 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
10855 return NUITKA_BOOL_EXCEPTION;
10856 }
10857#endif
10858
10859 PyTypeObject *type1 = Py_TYPE(operand1);
10860
10861#if PYTHON_VERSION < 0x300
10862 // If the types are equal, we may get away immediately except for instances.
10863 if (type1 == &PyList_Type && !0) {
10864
10865 richcmpfunc frich = PyList_Type.tp_richcompare;
10866
10867 if (frich != NULL) {
10868 PyObject *result = (*frich)(operand1, operand2, Py_GT);
10869
10870 if (result != Py_NotImplemented) {
10871 Py_LeaveRecursiveCall();
10872
10873 if (unlikely(result == NULL)) {
10874 return NUITKA_BOOL_EXCEPTION;
10875 }
10876
10877 {
10878 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10879 Py_DECREF(result);
10880 return r;
10881 }
10882 }
10883
10884 Py_DECREF_IMMORTAL(result);
10885 }
10886
10887 // No rich comparison worked, but maybe compare works.
10888 cmpfunc fcmp = NULL;
10889
10890 if (fcmp != NULL) {
10891 int c = (*fcmp)(operand1, operand2);
10892 c = adjust_tp_compare(c);
10893
10894 Py_LeaveRecursiveCall();
10895
10896 if (c == -2) {
10897 return NUITKA_BOOL_EXCEPTION;
10898 }
10899
10900 switch (Py_GT) {
10901 case Py_LT:
10902 c = c < 0;
10903 break;
10904 case Py_LE:
10905 c = c <= 0;
10906 break;
10907 case Py_EQ:
10908 c = c == 0;
10909 break;
10910 case Py_NE:
10911 c = c != 0;
10912 break;
10913 case Py_GT:
10914 c = c > 0;
10915 break;
10916 case Py_GE:
10917 c = c >= 0;
10918 break;
10919 default:
10920 NUITKA_CANNOT_GET_HERE("wrong op_code");
10921 }
10922
10923 bool r = c != 0;
10924 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10925
10926 return result;
10927 }
10928 }
10929
10930 // Fast path was not successful or not taken
10931 richcmpfunc f;
10932
10933 if (type1 != &PyList_Type && 0) {
10934 f = PyList_Type.tp_richcompare;
10935
10936 if (f != NULL) {
10937 PyObject *result = (*f)(operand2, operand1, Py_LT);
10938
10939 if (result != Py_NotImplemented) {
10940 Py_LeaveRecursiveCall();
10941
10942 if (unlikely(result == NULL)) {
10943 return NUITKA_BOOL_EXCEPTION;
10944 }
10945
10946 {
10947 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10948 Py_DECREF(result);
10949 return r;
10950 }
10951 }
10952
10953 Py_DECREF_IMMORTAL(result);
10954 }
10955 }
10956
10957 f = TP_RICHCOMPARE(type1);
10958 if (f != NULL) {
10959 PyObject *result = (*f)(operand1, operand2, Py_GT);
10960
10961 if (result != Py_NotImplemented) {
10962 Py_LeaveRecursiveCall();
10963
10964 if (unlikely(result == NULL)) {
10965 return NUITKA_BOOL_EXCEPTION;
10966 }
10967
10968 {
10969 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10970 Py_DECREF(result);
10971 return r;
10972 }
10973 }
10974
10975 Py_DECREF_IMMORTAL(result);
10976 }
10977
10978 f = PyList_Type.tp_richcompare;
10979 if (f != NULL) {
10980 PyObject *result = (*f)(operand2, operand1, Py_LT);
10981
10982 if (result != Py_NotImplemented) {
10983 Py_LeaveRecursiveCall();
10984
10985 if (unlikely(result == NULL)) {
10986 return NUITKA_BOOL_EXCEPTION;
10987 }
10988
10989 {
10990 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
10991 Py_DECREF(result);
10992 return r;
10993 }
10994 }
10995
10996 Py_DECREF_IMMORTAL(result);
10997 }
10998
10999 int c;
11000
11001 if (PyInstance_Check(operand1)) {
11002 cmpfunc fcmp = type1->tp_compare;
11003 c = (*fcmp)(operand1, operand2);
11004 } else if (0) {
11005 cmpfunc fcmp = NULL;
11006 c = (*fcmp)(operand1, operand2);
11007 } else {
11008 c = try_3way_compare(operand1, operand2);
11009 }
11010
11011 if (c >= 2) {
11012 if (type1 == &PyList_Type) {
11013 Py_uintptr_t aa = (Py_uintptr_t)operand1;
11014 Py_uintptr_t bb = (Py_uintptr_t)operand2;
11015
11016 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11017 } else if (operand1 == Py_None) {
11018 // None is smaller than everything else
11019 c = -1;
11020 } else if (operand2 == Py_None) {
11021 // None is smaller than everything else
11022 c = 1;
11023 } else if (PyNumber_Check(operand1)) {
11024 // different type: compare type names but numbers are smaller than
11025 // others.
11026 if (PyNumber_Check(operand2)) {
11027 // Both numbers, need to make a decision based on types.
11028 Py_uintptr_t aa = (Py_uintptr_t)type1;
11029 Py_uintptr_t bb = (Py_uintptr_t)&PyList_Type;
11030
11031 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11032 } else {
11033 c = -1;
11034 }
11035 } else if (PyNumber_Check(operand2)) {
11036 c = 1;
11037 } else {
11038 // Banking on C compile to optimize "strcmp".
11039 int s = strcmp(type1->tp_name, "list");
11040
11041 if (s < 0) {
11042 c = -1;
11043 } else if (s > 0) {
11044 c = 1;
11045 } else {
11046 // Same type name need to make a decision based on type address.
11047 Py_uintptr_t aa = (Py_uintptr_t)type1;
11048 Py_uintptr_t bb = (Py_uintptr_t)&PyList_Type;
11049
11050 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11051 }
11052 }
11053 }
11054
11055 Py_LeaveRecursiveCall();
11056
11057 if (unlikely(c <= -2)) {
11058 return NUITKA_BOOL_EXCEPTION;
11059 }
11060
11061 switch (Py_GT) {
11062 case Py_LT:
11063 c = c < 0;
11064 break;
11065 case Py_LE:
11066 c = c <= 0;
11067 break;
11068 case Py_EQ:
11069 c = c == 0;
11070 break;
11071 case Py_NE:
11072 c = c != 0;
11073 break;
11074 case Py_GT:
11075 c = c > 0;
11076 break;
11077 case Py_GE:
11078 c = c >= 0;
11079 break;
11080 }
11081
11082 bool r = c != 0;
11083 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11084
11085 return result;
11086#else
11087 bool checked_reverse_op = false;
11088 richcmpfunc f;
11089
11090 if (type1 != &PyList_Type && Nuitka_Type_IsSubtype(&PyList_Type, type1)) {
11091 f = PyList_Type.tp_richcompare;
11092
11093 if (f != NULL) {
11094 checked_reverse_op = true;
11095
11096 PyObject *result = (*f)(operand2, operand1, Py_LT);
11097
11098 if (result != Py_NotImplemented) {
11099 Py_LeaveRecursiveCall();
11100
11101 if (unlikely(result == NULL)) {
11102 return NUITKA_BOOL_EXCEPTION;
11103 }
11104
11105 {
11106 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11107 Py_DECREF(result);
11108 return r;
11109 }
11110 }
11111
11112 Py_DECREF_IMMORTAL(result);
11113 }
11114 }
11115
11116 f = TP_RICHCOMPARE(type1);
11117
11118 if (f != NULL) {
11119 PyObject *result = (*f)(operand1, operand2, Py_GT);
11120
11121 if (result != Py_NotImplemented) {
11122 Py_LeaveRecursiveCall();
11123
11124 if (unlikely(result == NULL)) {
11125 return NUITKA_BOOL_EXCEPTION;
11126 }
11127
11128 {
11129 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11130 Py_DECREF(result);
11131 return r;
11132 }
11133 }
11134
11135 Py_DECREF_IMMORTAL(result);
11136 }
11137
11138 if (checked_reverse_op == false) {
11139 f = PyList_Type.tp_richcompare;
11140
11141 if (f != NULL) {
11142 PyObject *result = (*f)(operand2, operand1, Py_LT);
11143
11144 if (result != Py_NotImplemented) {
11145 Py_LeaveRecursiveCall();
11146
11147 if (unlikely(result == NULL)) {
11148 return NUITKA_BOOL_EXCEPTION;
11149 }
11150
11151 {
11152 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11153 Py_DECREF(result);
11154 return r;
11155 }
11156 }
11157
11158 Py_DECREF_IMMORTAL(result);
11159 }
11160 }
11161
11162 Py_LeaveRecursiveCall();
11163
11164 // If it is not implemented, do pointer identity checks as "==" and "!=" and
11165 // otherwise give an error
11166 switch (Py_GT) {
11167 case Py_EQ: {
11168 bool r = operand1 == operand2;
11169 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11170
11171 return result;
11172 }
11173 case Py_NE: {
11174 bool r = operand1 != operand2;
11175 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11176
11177 return result;
11178 }
11179 default:
11180#if PYTHON_VERSION < 0x360
11181 PyErr_Format(PyExc_TypeError, "unorderable types: %s() > list()", type1->tp_name);
11182#else
11183 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of '%s' and 'list'", type1->tp_name);
11184#endif
11185 return NUITKA_BOOL_EXCEPTION;
11186 }
11187#endif
11188}
11189
11190/* Code referring to "LIST" corresponds to Python 'list' and "OBJECT" to any Python object. */
11191nuitka_bool RICH_COMPARE_GT_NBOOL_LIST_OBJECT(PyObject *operand1, PyObject *operand2) {
11192
11193 if (&PyList_Type == Py_TYPE(operand2)) {
11194 return COMPARE_GT_NBOOL_LIST_LIST(operand1, operand2);
11195 }
11196
11197#if PYTHON_VERSION < 0x300
11198 if (unlikely(Py_EnterRecursiveCall((char *)" in cmp"))) {
11199 return NUITKA_BOOL_EXCEPTION;
11200 }
11201#else
11202 if (unlikely(Py_EnterRecursiveCall((char *)" in comparison"))) {
11203 return NUITKA_BOOL_EXCEPTION;
11204 }
11205#endif
11206
11207 PyTypeObject *type2 = Py_TYPE(operand2);
11208
11209#if PYTHON_VERSION < 0x300
11210 // If the types are equal, we may get away immediately except for instances.
11211 if (&PyList_Type == type2 && !0) {
11212
11213 richcmpfunc frich = PyList_Type.tp_richcompare;
11214
11215 if (frich != NULL) {
11216 PyObject *result = (*frich)(operand1, operand2, Py_GT);
11217
11218 if (result != Py_NotImplemented) {
11219 Py_LeaveRecursiveCall();
11220
11221 if (unlikely(result == NULL)) {
11222 return NUITKA_BOOL_EXCEPTION;
11223 }
11224
11225 {
11226 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11227 Py_DECREF(result);
11228 return r;
11229 }
11230 }
11231
11232 Py_DECREF_IMMORTAL(result);
11233 }
11234
11235 // No rich comparison worked, but maybe compare works.
11236 cmpfunc fcmp = NULL;
11237
11238 if (fcmp != NULL) {
11239 int c = (*fcmp)(operand1, operand2);
11240 c = adjust_tp_compare(c);
11241
11242 Py_LeaveRecursiveCall();
11243
11244 if (c == -2) {
11245 return NUITKA_BOOL_EXCEPTION;
11246 }
11247
11248 switch (Py_GT) {
11249 case Py_LT:
11250 c = c < 0;
11251 break;
11252 case Py_LE:
11253 c = c <= 0;
11254 break;
11255 case Py_EQ:
11256 c = c == 0;
11257 break;
11258 case Py_NE:
11259 c = c != 0;
11260 break;
11261 case Py_GT:
11262 c = c > 0;
11263 break;
11264 case Py_GE:
11265 c = c >= 0;
11266 break;
11267 default:
11268 NUITKA_CANNOT_GET_HERE("wrong op_code");
11269 }
11270
11271 bool r = c != 0;
11272 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11273
11274 return result;
11275 }
11276 }
11277
11278 // Fast path was not successful or not taken
11279 richcmpfunc f;
11280
11281 if (&PyList_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyList_Type)) {
11282 f = TP_RICHCOMPARE(type2);
11283
11284 if (f != NULL) {
11285 PyObject *result = (*f)(operand2, operand1, Py_LT);
11286
11287 if (result != Py_NotImplemented) {
11288 Py_LeaveRecursiveCall();
11289
11290 if (unlikely(result == NULL)) {
11291 return NUITKA_BOOL_EXCEPTION;
11292 }
11293
11294 {
11295 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11296 Py_DECREF(result);
11297 return r;
11298 }
11299 }
11300
11301 Py_DECREF_IMMORTAL(result);
11302 }
11303 }
11304
11305 f = PyList_Type.tp_richcompare;
11306 if (f != NULL) {
11307 PyObject *result = (*f)(operand1, operand2, Py_GT);
11308
11309 if (result != Py_NotImplemented) {
11310 Py_LeaveRecursiveCall();
11311
11312 if (unlikely(result == NULL)) {
11313 return NUITKA_BOOL_EXCEPTION;
11314 }
11315
11316 {
11317 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11318 Py_DECREF(result);
11319 return r;
11320 }
11321 }
11322
11323 Py_DECREF_IMMORTAL(result);
11324 }
11325
11326 f = TP_RICHCOMPARE(type2);
11327 if (f != NULL) {
11328 PyObject *result = (*f)(operand2, operand1, Py_LT);
11329
11330 if (result != Py_NotImplemented) {
11331 Py_LeaveRecursiveCall();
11332
11333 if (unlikely(result == NULL)) {
11334 return NUITKA_BOOL_EXCEPTION;
11335 }
11336
11337 {
11338 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11339 Py_DECREF(result);
11340 return r;
11341 }
11342 }
11343
11344 Py_DECREF_IMMORTAL(result);
11345 }
11346
11347 int c;
11348
11349 if (0) {
11350 cmpfunc fcmp = NULL;
11351 c = (*fcmp)(operand1, operand2);
11352 } else if (PyInstance_Check(operand2)) {
11353 cmpfunc fcmp = type2->tp_compare;
11354 c = (*fcmp)(operand1, operand2);
11355 } else {
11356 c = try_3way_compare(operand1, operand2);
11357 }
11358
11359 if (c >= 2) {
11360 if (&PyList_Type == type2) {
11361 Py_uintptr_t aa = (Py_uintptr_t)operand1;
11362 Py_uintptr_t bb = (Py_uintptr_t)operand2;
11363
11364 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11365 } else if (operand1 == Py_None) {
11366 // None is smaller than everything else
11367 c = -1;
11368 } else if (operand2 == Py_None) {
11369 // None is smaller than everything else
11370 c = 1;
11371 } else if (PyNumber_Check(operand1)) {
11372 // different type: compare type names but numbers are smaller than
11373 // others.
11374 if (PyNumber_Check(operand2)) {
11375 // Both numbers, need to make a decision based on types.
11376 Py_uintptr_t aa = (Py_uintptr_t)&PyList_Type;
11377 Py_uintptr_t bb = (Py_uintptr_t)type2;
11378
11379 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11380 } else {
11381 c = -1;
11382 }
11383 } else if (PyNumber_Check(operand2)) {
11384 c = 1;
11385 } else {
11386 // Banking on C compile to optimize "strcmp".
11387 int s = strcmp("list", type2->tp_name);
11388
11389 if (s < 0) {
11390 c = -1;
11391 } else if (s > 0) {
11392 c = 1;
11393 } else {
11394 // Same type name need to make a decision based on type address.
11395 Py_uintptr_t aa = (Py_uintptr_t)&PyList_Type;
11396 Py_uintptr_t bb = (Py_uintptr_t)type2;
11397
11398 c = (aa < bb) ? -1 : (aa > bb) ? 1 : 0;
11399 }
11400 }
11401 }
11402
11403 Py_LeaveRecursiveCall();
11404
11405 if (unlikely(c <= -2)) {
11406 return NUITKA_BOOL_EXCEPTION;
11407 }
11408
11409 switch (Py_GT) {
11410 case Py_LT:
11411 c = c < 0;
11412 break;
11413 case Py_LE:
11414 c = c <= 0;
11415 break;
11416 case Py_EQ:
11417 c = c == 0;
11418 break;
11419 case Py_NE:
11420 c = c != 0;
11421 break;
11422 case Py_GT:
11423 c = c > 0;
11424 break;
11425 case Py_GE:
11426 c = c >= 0;
11427 break;
11428 }
11429
11430 bool r = c != 0;
11431 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11432
11433 return result;
11434#else
11435 bool checked_reverse_op = false;
11436 richcmpfunc f;
11437
11438 if (&PyList_Type != type2 && Nuitka_Type_IsSubtype(type2, &PyList_Type)) {
11439 f = TP_RICHCOMPARE(type2);
11440
11441 if (f != NULL) {
11442 checked_reverse_op = true;
11443
11444 PyObject *result = (*f)(operand2, operand1, Py_LT);
11445
11446 if (result != Py_NotImplemented) {
11447 Py_LeaveRecursiveCall();
11448
11449 if (unlikely(result == NULL)) {
11450 return NUITKA_BOOL_EXCEPTION;
11451 }
11452
11453 {
11454 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11455 Py_DECREF(result);
11456 return r;
11457 }
11458 }
11459
11460 Py_DECREF_IMMORTAL(result);
11461 }
11462 }
11463
11464 f = PyList_Type.tp_richcompare;
11465
11466 if (f != NULL) {
11467 PyObject *result = (*f)(operand1, operand2, Py_GT);
11468
11469 if (result != Py_NotImplemented) {
11470 Py_LeaveRecursiveCall();
11471
11472 if (unlikely(result == NULL)) {
11473 return NUITKA_BOOL_EXCEPTION;
11474 }
11475
11476 {
11477 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11478 Py_DECREF(result);
11479 return r;
11480 }
11481 }
11482
11483 Py_DECREF_IMMORTAL(result);
11484 }
11485
11486 if (checked_reverse_op == false) {
11487 f = TP_RICHCOMPARE(type2);
11488
11489 if (f != NULL) {
11490 PyObject *result = (*f)(operand2, operand1, Py_LT);
11491
11492 if (result != Py_NotImplemented) {
11493 Py_LeaveRecursiveCall();
11494
11495 if (unlikely(result == NULL)) {
11496 return NUITKA_BOOL_EXCEPTION;
11497 }
11498
11499 {
11500 nuitka_bool r = CHECK_IF_TRUE(result) ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11501 Py_DECREF(result);
11502 return r;
11503 }
11504 }
11505
11506 Py_DECREF_IMMORTAL(result);
11507 }
11508 }
11509
11510 Py_LeaveRecursiveCall();
11511
11512 // If it is not implemented, do pointer identity checks as "==" and "!=" and
11513 // otherwise give an error
11514 switch (Py_GT) {
11515 case Py_EQ: {
11516 bool r = operand1 == operand2;
11517 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11518
11519 return result;
11520 }
11521 case Py_NE: {
11522 bool r = operand1 != operand2;
11523 nuitka_bool result = r ? NUITKA_BOOL_TRUE : NUITKA_BOOL_FALSE;
11524
11525 return result;
11526 }
11527 default:
11528#if PYTHON_VERSION < 0x360
11529 PyErr_Format(PyExc_TypeError, "unorderable types: list() > %s()", type2->tp_name);
11530#else
11531 PyErr_Format(PyExc_TypeError, "'>' not supported between instances of 'list' and '%s'", type2->tp_name);
11532#endif
11533 return NUITKA_BOOL_EXCEPTION;
11534 }
11535#endif
11536}
11537
11538/* Code referring to "LIST" corresponds to Python 'list' and "LIST" to Python 'list'. */
11539nuitka_bool RICH_COMPARE_GT_NBOOL_LIST_LIST(PyObject *operand1, PyObject *operand2) {
11540
11541 return COMPARE_GT_NBOOL_LIST_LIST(operand1, operand2);
11542}
11543
11544static PyObject *COMPARE_GT_OBJECT_LONG_CLONG(PyObject *operand1, long operand2) {
11545 CHECK_OBJECT(operand1);
11546 assert(PyLong_CheckExact(operand1));
11547
11548 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
11549
11550 bool operand2_is_negative;
11551 unsigned long operand2_abs_ival;
11552
11553 if (operand2 < 0) {
11554 operand2_abs_ival = (unsigned long)(-1 - operand2) + 1;
11555 operand2_is_negative = true;
11556 } else {
11557 operand2_abs_ival = (unsigned long)operand2;
11558 operand2_is_negative = false;
11559 }
11560
11561 Py_ssize_t operand2_digit_count = 0;
11562 digit operand2_digits[5] = {0}; // Could be more minimal and depend on sizeof(digit)
11563 {
11564 unsigned long t = operand2_abs_ival;
11565
11566 while (t != 0) {
11567 operand2_digit_count += 1;
11568 assert(operand2_digit_count <= (Py_ssize_t)(sizeof(operand2_digit_count) / sizeof(digit)));
11569
11570 operand2_digits[operand2_digit_count] = (digit)(t & PyLong_MASK);
11571 t >>= PyLong_SHIFT;
11572 }
11573 }
11574
11575 NUITKA_MAY_BE_UNUSED Py_ssize_t operand2_size =
11576 operand2_is_negative == false ? operand2_digit_count : -operand2_digit_count;
11577
11578 bool r;
11579
11580 if (Nuitka_LongGetSignedDigitSize(operand1_long_object) != operand2_size) {
11581 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) - operand2_size > 0;
11582 } else {
11583 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
11584 r = false;
11585 while (--i >= 0) {
11586 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] != operand2_digits[i]) {
11587 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] > operand2_digits[i];
11588 if (Nuitka_LongIsNegative(operand1_long_object)) {
11589 r = !r;
11590 }
11591 break;
11592 }
11593 }
11594 }
11595
11596 // Convert to target type.
11597 PyObject *result = BOOL_FROM(r);
11598 Py_INCREF_IMMORTAL(result);
11599 return result;
11600}
11601#if PYTHON_VERSION < 0x300
11602/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
11603PyObject *RICH_COMPARE_GT_OBJECT_LONG_INT(PyObject *operand1, PyObject *operand2) {
11604
11605 return COMPARE_GT_OBJECT_LONG_CLONG(operand1, PyInt_AS_LONG(operand1));
11606}
11607#endif
11608
11609static bool COMPARE_GT_CBOOL_LONG_CLONG(PyObject *operand1, long operand2) {
11610 CHECK_OBJECT(operand1);
11611 assert(PyLong_CheckExact(operand1));
11612
11613 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
11614
11615 bool operand2_is_negative;
11616 unsigned long operand2_abs_ival;
11617
11618 if (operand2 < 0) {
11619 operand2_abs_ival = (unsigned long)(-1 - operand2) + 1;
11620 operand2_is_negative = true;
11621 } else {
11622 operand2_abs_ival = (unsigned long)operand2;
11623 operand2_is_negative = false;
11624 }
11625
11626 Py_ssize_t operand2_digit_count = 0;
11627 digit operand2_digits[5] = {0}; // Could be more minimal and depend on sizeof(digit)
11628 {
11629 unsigned long t = operand2_abs_ival;
11630
11631 while (t != 0) {
11632 operand2_digit_count += 1;
11633 assert(operand2_digit_count <= (Py_ssize_t)(sizeof(operand2_digit_count) / sizeof(digit)));
11634
11635 operand2_digits[operand2_digit_count] = (digit)(t & PyLong_MASK);
11636 t >>= PyLong_SHIFT;
11637 }
11638 }
11639
11640 NUITKA_MAY_BE_UNUSED Py_ssize_t operand2_size =
11641 operand2_is_negative == false ? operand2_digit_count : -operand2_digit_count;
11642
11643 bool r;
11644
11645 if (Nuitka_LongGetSignedDigitSize(operand1_long_object) != operand2_size) {
11646 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) - operand2_size > 0;
11647 } else {
11648 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
11649 r = false;
11650 while (--i >= 0) {
11651 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] != operand2_digits[i]) {
11652 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] > operand2_digits[i];
11653 if (Nuitka_LongIsNegative(operand1_long_object)) {
11654 r = !r;
11655 }
11656 break;
11657 }
11658 }
11659 }
11660
11661 // Convert to target type.
11662 bool result = r;
11663
11664 return result;
11665}
11666#if PYTHON_VERSION < 0x300
11667/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
11668bool RICH_COMPARE_GT_CBOOL_LONG_INT(PyObject *operand1, PyObject *operand2) {
11669
11670 return COMPARE_GT_CBOOL_LONG_CLONG(operand1, PyInt_AS_LONG(operand1));
11671}
11672#endif
11673
11674#if PYTHON_VERSION < 0x300
11675static PyObject *COMPARE_GT_OBJECT_INT_CLONG(PyObject *operand1, long operand2) {
11676 CHECK_OBJECT(operand1);
11677 assert(PyInt_CheckExact(operand1));
11678
11679 const long a = PyInt_AS_LONG(operand1);
11680 const long b = operand2;
11681
11682 bool r = a > b;
11683
11684 // Convert to target type.
11685 PyObject *result = BOOL_FROM(r);
11686 Py_INCREF_IMMORTAL(result);
11687 return result;
11688}
11689#endif
11690#if PYTHON_VERSION < 0x300
11691/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
11692PyObject *RICH_COMPARE_GT_OBJECT_INT_CLONG(PyObject *operand1, long operand2) {
11693
11694 return COMPARE_GT_OBJECT_INT_CLONG(operand1, operand2);
11695}
11696#endif
11697
11698#if PYTHON_VERSION < 0x300
11699static bool COMPARE_GT_CBOOL_INT_CLONG(PyObject *operand1, long operand2) {
11700 CHECK_OBJECT(operand1);
11701 assert(PyInt_CheckExact(operand1));
11702
11703 const long a = PyInt_AS_LONG(operand1);
11704 const long b = operand2;
11705
11706 bool r = a > b;
11707
11708 // Convert to target type.
11709 bool result = r;
11710
11711 return result;
11712}
11713#endif
11714#if PYTHON_VERSION < 0x300
11715/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
11716bool RICH_COMPARE_GT_CBOOL_INT_CLONG(PyObject *operand1, long operand2) {
11717
11718 return COMPARE_GT_CBOOL_INT_CLONG(operand1, operand2);
11719}
11720#endif
11721
11722static PyObject *COMPARE_GT_OBJECT_LONG_DIGIT(PyObject *operand1, long operand2) {
11723 CHECK_OBJECT(operand1);
11724 assert(PyLong_CheckExact(operand1));
11725 assert(Py_ABS(operand2) < (1 << PyLong_SHIFT));
11726
11727 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
11728
11729 bool r;
11730
11731 if (Nuitka_LongGetSignedDigitSize(operand1_long_object) !=
11732 (Py_ssize_t)((operand2 == 0) ? 0 : ((operand2 < 0) ? -1 : 1))) {
11733 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) -
11734 (Py_ssize_t)((operand2 == 0) ? 0 : ((operand2 < 0) ? -1 : 1)) >
11735 0;
11736 } else {
11737 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
11738 r = false;
11739 while (--i >= 0) {
11740 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] != (digit)Py_ABS(operand2)) {
11741 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] > (digit)Py_ABS(operand2);
11742 if (Nuitka_LongIsNegative(operand1_long_object)) {
11743 r = !r;
11744 }
11745 break;
11746 }
11747 }
11748 }
11749
11750 // Convert to target type.
11751 PyObject *result = BOOL_FROM(r);
11752 Py_INCREF_IMMORTAL(result);
11753 return result;
11754}
11755/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "DIGIT" to C platform digit value for long
11756 * Python objects. */
11757PyObject *RICH_COMPARE_GT_OBJECT_LONG_DIGIT(PyObject *operand1, long operand2) {
11758
11759 return COMPARE_GT_OBJECT_LONG_DIGIT(operand1, operand2);
11760}
11761
11762static bool COMPARE_GT_CBOOL_LONG_DIGIT(PyObject *operand1, long operand2) {
11763 CHECK_OBJECT(operand1);
11764 assert(PyLong_CheckExact(operand1));
11765 assert(Py_ABS(operand2) < (1 << PyLong_SHIFT));
11766
11767 PyLongObject *operand1_long_object = (PyLongObject *)operand1;
11768
11769 bool r;
11770
11771 if (Nuitka_LongGetSignedDigitSize(operand1_long_object) !=
11772 (Py_ssize_t)((operand2 == 0) ? 0 : ((operand2 < 0) ? -1 : 1))) {
11773 r = Nuitka_LongGetSignedDigitSize(operand1_long_object) -
11774 (Py_ssize_t)((operand2 == 0) ? 0 : ((operand2 < 0) ? -1 : 1)) >
11775 0;
11776 } else {
11777 Py_ssize_t i = Nuitka_LongGetDigitSize(operand1_long_object);
11778 r = false;
11779 while (--i >= 0) {
11780 if (Nuitka_LongGetDigitPointer(operand1_long_object)[i] != (digit)Py_ABS(operand2)) {
11781 r = Nuitka_LongGetDigitPointer(operand1_long_object)[i] > (digit)Py_ABS(operand2);
11782 if (Nuitka_LongIsNegative(operand1_long_object)) {
11783 r = !r;
11784 }
11785 break;
11786 }
11787 }
11788 }
11789
11790 // Convert to target type.
11791 bool result = r;
11792
11793 return result;
11794}
11795/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "DIGIT" to C platform digit value for long
11796 * Python objects. */
11797bool RICH_COMPARE_GT_CBOOL_LONG_DIGIT(PyObject *operand1, long operand2) {
11798
11799 return COMPARE_GT_CBOOL_LONG_DIGIT(operand1, operand2);
11800}
11801
11802static PyObject *COMPARE_GT_OBJECT_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
11803 CHECK_OBJECT(operand1);
11804 assert(PyFloat_CheckExact(operand1));
11805
11806 const double a = PyFloat_AS_DOUBLE(operand1);
11807 const double b = operand2;
11808
11809 bool r = a > b;
11810
11811 // Convert to target type.
11812 PyObject *result = BOOL_FROM(r);
11813 Py_INCREF_IMMORTAL(result);
11814 return result;
11815}
11816/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
11817PyObject *RICH_COMPARE_GT_OBJECT_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
11818
11819 return COMPARE_GT_OBJECT_FLOAT_CFLOAT(operand1, operand2);
11820}
11821
11822static bool COMPARE_GT_CBOOL_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
11823 CHECK_OBJECT(operand1);
11824 assert(PyFloat_CheckExact(operand1));
11825
11826 const double a = PyFloat_AS_DOUBLE(operand1);
11827 const double b = operand2;
11828
11829 bool r = a > b;
11830
11831 // Convert to target type.
11832 bool result = r;
11833
11834 return result;
11835}
11836/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
11837bool RICH_COMPARE_GT_CBOOL_FLOAT_CFLOAT(PyObject *operand1, double operand2) {
11838
11839 return COMPARE_GT_CBOOL_FLOAT_CFLOAT(operand1, operand2);
11840}
11841
11842// Part of "Nuitka", an optimizing Python compiler that is compatible and
11843// integrates with CPython, but also works on its own.
11844//
11845// Licensed under the Apache License, Version 2.0 (the "License");
11846// you may not use this file except in compliance with the License.
11847// You may obtain a copy of the License at
11848//
11849// http://www.apache.org/licenses/LICENSE-2.0
11850//
11851// Unless required by applicable law or agreed to in writing, software
11852// distributed under the License is distributed on an "AS IS" BASIS,
11853// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11854// See the License for the specific language governing permissions and
11855// limitations under the License.