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