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