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