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