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