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