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