Nuitka
The Python compiler
Loading...
Searching...
No Matches
HelpersOperationInplaceMult.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 HelperOperationInplace.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 in-place "*" (MULT) operations */
11
12#if PYTHON_VERSION < 0x300
13/* Code referring to "INT" corresponds to Python2 'int' and "INT" to Python2 'int'. */
14static inline bool _INPLACE_OPERATION_MULT_INT_INT(PyObject **operand1, PyObject *operand2) {
15 assert(operand1); // Pointer must be non-null.
16
17 CHECK_OBJECT(*operand1);
18 assert(PyInt_CheckExact(*operand1));
19 CHECK_OBJECT(operand2);
20 assert(PyInt_CheckExact(operand2));
21
22 // Not every code path will make use of all possible results.
23#if defined(_MSC_VER)
24#pragma warning(push)
25#pragma warning(disable : 4101)
26#endif
27 NUITKA_MAY_BE_UNUSED bool cbool_result;
28 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
29 NUITKA_MAY_BE_UNUSED long clong_result;
30 NUITKA_MAY_BE_UNUSED double cfloat_result;
31#if defined(_MSC_VER)
32#pragma warning(pop)
33#endif
34
35 CHECK_OBJECT(*operand1);
36 assert(PyInt_CheckExact(*operand1));
37 CHECK_OBJECT(operand2);
38 assert(PyInt_CheckExact(operand2));
39
40 const long a = PyInt_AS_LONG(*operand1);
41 const long b = PyInt_AS_LONG(operand2);
42
43 const long longprod = (long)((unsigned long)a * b);
44 const double doubleprod = (double)a * (double)b;
45 const double doubled_longprod = (double)longprod;
46
47 if (likely(doubled_longprod == doubleprod)) {
48 clong_result = longprod;
49 goto exit_result_ok_clong;
50 } else {
51 const double diff = doubled_longprod - doubleprod;
52 const double absdiff = diff >= 0.0 ? diff : -diff;
53 const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod;
54
55 if (likely(32.0 * absdiff <= absprod)) {
56 clong_result = longprod;
57 goto exit_result_ok_clong;
58 }
59 }
60
61 {
62 PyObject *operand1_object = *operand1;
63 PyObject *operand2_object = operand2;
64
65 PyObject *r = PyLong_Type.tp_as_number->nb_multiply(operand1_object, operand2_object);
66 assert(r != Py_NotImplemented);
67
68 obj_result = r;
69 goto exit_result_object;
70 }
71
72exit_result_ok_clong:
73
74 // We got an object handed, that we have to release.
75 Py_DECREF(*operand1);
76
77 // That's our return value then. As we use a dedicated variable, it's
78 // OK that way.
79 *operand1 = Nuitka_PyInt_FromLong(clong_result);
80 goto exit_result_ok;
81
82exit_result_object:
83 if (unlikely(obj_result == NULL)) {
84 goto exit_result_exception;
85 }
86 // We got an object handed, that we have to release.
87 Py_DECREF(*operand1);
88
89 *operand1 = obj_result;
90 goto exit_result_ok;
91
92exit_result_ok:
93 return true;
94
95exit_result_exception:
96 return false;
97}
98
99bool INPLACE_OPERATION_MULT_INT_INT(PyObject **operand1, PyObject *operand2) {
100 return _INPLACE_OPERATION_MULT_INT_INT(operand1, operand2);
101}
102#endif
103
104#if PYTHON_VERSION < 0x300
105/* Code referring to "OBJECT" corresponds to any Python object and "INT" to Python2 'int'. */
106static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
107 PyTypeObject *type1 = Py_TYPE(*operand1);
108
109#if defined(_MSC_VER)
110#pragma warning(push)
111#pragma warning(disable : 4101)
112#endif
113 NUITKA_MAY_BE_UNUSED bool cbool_result;
114 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
115#if defined(_MSC_VER)
116#pragma warning(pop)
117#endif
118
119 binaryfunc islot =
120 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_multiply : NULL;
121
122 if (islot != NULL) {
123 PyObject *x = islot(*operand1, operand2);
124
125 if (x != Py_NotImplemented) {
126 obj_result = x;
127 goto exit_inplace_result_object;
128 }
129
130 Py_DECREF_IMMORTAL(x);
131 }
132
133 {
134 binaryfunc slot1 =
135 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_multiply : NULL;
136 binaryfunc slot2 = NULL;
137
138 if (!(type1 == &PyInt_Type)) {
139 // Different types, need to consider second value slot.
140
141 slot2 = PyInt_Type.tp_as_number->nb_multiply;
142
143 if (slot1 == slot2) {
144 slot2 = NULL;
145 }
146 }
147
148 if (slot1 != NULL) {
149 PyObject *x = slot1(*operand1, operand2);
150
151 if (x != Py_NotImplemented) {
152 obj_result = x;
153 goto exit_inplace_result_object;
154 }
155
156 Py_DECREF_IMMORTAL(x);
157 }
158
159 if (slot2 != NULL) {
160 PyObject *x = slot2(*operand1, operand2);
161
162 if (x != Py_NotImplemented) {
163 obj_result = x;
164 goto exit_inplace_result_object;
165 }
166
167 Py_DECREF_IMMORTAL(x);
168 }
169
170#if PYTHON_VERSION < 0x300
171 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
172 coercion c1 =
173 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
174
175 if (c1 != NULL) {
176 PyObject *coerced1 = *operand1;
177 PyObject *coerced2 = operand2;
178
179 int err = c1(&coerced1, &coerced2);
180
181 if (unlikely(err < 0)) {
182 goto exit_inplace_exception;
183 }
184
185 if (err == 0) {
186 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
187
188 if (likely(mv == NULL)) {
189 binaryfunc slot = mv->nb_multiply;
190
191 if (likely(slot != NULL)) {
192 PyObject *x = slot(coerced1, coerced2);
193
194 Py_DECREF(coerced1);
195 Py_DECREF(coerced2);
196
197 obj_result = x;
198 goto exit_inplace_result_object;
199 }
200 }
201
202 // nb_coerce took a reference.
203 Py_DECREF(coerced1);
204 Py_DECREF(coerced2);
205 }
206 }
207 coercion c2 = PyInt_Type.tp_as_number->nb_coerce;
208
209 if (c2 != NULL) {
210 PyObject *coerced1 = *operand1;
211 PyObject *coerced2 = operand2;
212
213 int err = c2(&coerced2, &coerced1);
214
215 if (unlikely(err < 0)) {
216 goto exit_inplace_exception;
217 }
218
219 if (err == 0) {
220 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
221
222 if (likely(mv == NULL)) {
223 binaryfunc slot = mv->nb_multiply;
224
225 if (likely(slot != NULL)) {
226 PyObject *x = slot(coerced1, coerced2);
227
228 Py_DECREF(coerced1);
229 Py_DECREF(coerced2);
230
231 obj_result = x;
232 goto exit_inplace_result_object;
233 }
234 }
235
236 // nb_coerce took a reference.
237 Py_DECREF(coerced1);
238 Py_DECREF(coerced2);
239 }
240 }
241 }
242#endif
243
244 {
245 // Special case for "+" and "*", also works as sequence concat/repeat.
246 ssizeargfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_inplace_repeat : NULL;
247 if (sq_slot == NULL) {
248 sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_repeat : NULL;
249 }
250
251 if (sq_slot != NULL) {
252 PyObject *result = SEQUENCE_REPEAT(sq_slot, *operand1, operand2);
253
254 obj_result = result;
255 goto exit_inplace_result_object;
256 }
257 }
258 // No sequence repeat slot sq_repeat available for this type.
259
260 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: '%s' and 'int'", type1->tp_name);
261 goto exit_inplace_exception;
262 }
263
264exit_inplace_result_object:
265 if (unlikely(obj_result == NULL)) {
266 return false;
267 }
268
269 // We got an object handed, that we have to release.
270 Py_DECREF(*operand1);
271
272 // That's our return value then. As we use a dedicated variable, it's
273 // OK that way.
274 *operand1 = obj_result;
275
276 return true;
277
278exit_inplace_exception:
279 return false;
280}
281static inline bool _INPLACE_OPERATION_MULT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
282 assert(operand1); // Pointer must be non-null.
283
284 CHECK_OBJECT(*operand1);
285 CHECK_OBJECT(operand2);
286 assert(PyInt_CheckExact(operand2));
287
288 PyTypeObject *type1 = Py_TYPE(*operand1);
289
290 if (type1 == &PyInt_Type) {
291 // return _BINARY_OPERATION_MULT_INT_INT_INPLACE(operand1, operand2);
292
293 // Not every code path will make use of all possible results.
294#if defined(_MSC_VER)
295#pragma warning(push)
296#pragma warning(disable : 4101)
297#endif
298 NUITKA_MAY_BE_UNUSED bool cbool_result;
299 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
300 NUITKA_MAY_BE_UNUSED long clong_result;
301 NUITKA_MAY_BE_UNUSED double cfloat_result;
302#if defined(_MSC_VER)
303#pragma warning(pop)
304#endif
305
306 CHECK_OBJECT(*operand1);
307 assert(PyInt_CheckExact(*operand1));
308 CHECK_OBJECT(operand2);
309 assert(PyInt_CheckExact(operand2));
310
311 const long a = PyInt_AS_LONG(*operand1);
312 const long b = PyInt_AS_LONG(operand2);
313
314 const long longprod = (long)((unsigned long)a * b);
315 const double doubleprod = (double)a * (double)b;
316 const double doubled_longprod = (double)longprod;
317
318 if (likely(doubled_longprod == doubleprod)) {
319 clong_result = longprod;
320 goto exit_result_ok_clong;
321 } else {
322 const double diff = doubled_longprod - doubleprod;
323 const double absdiff = diff >= 0.0 ? diff : -diff;
324 const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod;
325
326 if (likely(32.0 * absdiff <= absprod)) {
327 clong_result = longprod;
328 goto exit_result_ok_clong;
329 }
330 }
331
332 {
333 PyObject *operand1_object = *operand1;
334 PyObject *operand2_object = operand2;
335
336 PyObject *r = PyLong_Type.tp_as_number->nb_multiply(operand1_object, operand2_object);
337 assert(r != Py_NotImplemented);
338
339 obj_result = r;
340 goto exit_result_object;
341 }
342
343 exit_result_ok_clong:
344
345 // We got an object handed, that we have to release.
346 Py_DECREF(*operand1);
347
348 // That's our return value then. As we use a dedicated variable, it's
349 // OK that way.
350 *operand1 = Nuitka_PyInt_FromLong(clong_result);
351 goto exit_result_ok;
352
353 exit_result_object:
354 if (unlikely(obj_result == NULL)) {
355 goto exit_result_exception;
356 }
357 // We got an object handed, that we have to release.
358 Py_DECREF(*operand1);
359
360 *operand1 = obj_result;
361 goto exit_result_ok;
362
363 exit_result_ok:
364 return true;
365
366 exit_result_exception:
367 return false;
368 }
369
370 return __INPLACE_OPERATION_MULT_OBJECT_INT(operand1, operand2);
371}
372
373bool INPLACE_OPERATION_MULT_OBJECT_INT(PyObject **operand1, PyObject *operand2) {
374 return _INPLACE_OPERATION_MULT_OBJECT_INT(operand1, operand2);
375}
376#endif
377
378#if PYTHON_VERSION < 0x300
379/* Code referring to "INT" corresponds to Python2 'int' and "OBJECT" to any Python object. */
380static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
381 PyTypeObject *type2 = Py_TYPE(operand2);
382
383#if defined(_MSC_VER)
384#pragma warning(push)
385#pragma warning(disable : 4101)
386#endif
387 NUITKA_MAY_BE_UNUSED bool cbool_result;
388 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
389#if defined(_MSC_VER)
390#pragma warning(pop)
391#endif
392
393 // No inplace number slot nb_inplace_multiply available for this type.
394
395 {
396 binaryfunc slot1 = PyInt_Type.tp_as_number->nb_multiply;
397 binaryfunc slot2 = NULL;
398
399 if (!(&PyInt_Type == type2)) {
400 // Different types, need to consider second value slot.
401
402 slot2 =
403 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
404
405 if (slot1 == slot2) {
406 slot2 = NULL;
407 }
408 }
409
410 if (slot1 != NULL) {
411 if (slot2 != NULL) {
412 if (Nuitka_Type_IsSubtype(type2, &PyInt_Type)) {
413 PyObject *x = slot2(*operand1, operand2);
414
415 if (x != Py_NotImplemented) {
416 obj_result = x;
417 goto exit_inplace_result_object;
418 }
419
420 Py_DECREF_IMMORTAL(x);
421 slot2 = NULL;
422 }
423 }
424
425 PyObject *x = slot1(*operand1, operand2);
426
427 if (x != Py_NotImplemented) {
428 obj_result = x;
429 goto exit_inplace_result_object;
430 }
431
432 Py_DECREF_IMMORTAL(x);
433 }
434
435 if (slot2 != NULL) {
436 PyObject *x = slot2(*operand1, operand2);
437
438 if (x != Py_NotImplemented) {
439 obj_result = x;
440 goto exit_inplace_result_object;
441 }
442
443 Py_DECREF_IMMORTAL(x);
444 }
445
446#if PYTHON_VERSION < 0x300
447 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
448 coercion c1 = PyInt_Type.tp_as_number->nb_coerce;
449
450 if (c1 != NULL) {
451 PyObject *coerced1 = *operand1;
452 PyObject *coerced2 = operand2;
453
454 int err = c1(&coerced1, &coerced2);
455
456 if (unlikely(err < 0)) {
457 goto exit_inplace_exception;
458 }
459
460 if (err == 0) {
461 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
462
463 if (likely(mv == NULL)) {
464 binaryfunc slot = mv->nb_multiply;
465
466 if (likely(slot != NULL)) {
467 PyObject *x = slot(coerced1, coerced2);
468
469 Py_DECREF(coerced1);
470 Py_DECREF(coerced2);
471
472 obj_result = x;
473 goto exit_inplace_result_object;
474 }
475 }
476
477 // nb_coerce took a reference.
478 Py_DECREF(coerced1);
479 Py_DECREF(coerced2);
480 }
481 }
482 coercion c2 =
483 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
484
485 if (c2 != NULL) {
486 PyObject *coerced1 = *operand1;
487 PyObject *coerced2 = operand2;
488
489 int err = c2(&coerced2, &coerced1);
490
491 if (unlikely(err < 0)) {
492 goto exit_inplace_exception;
493 }
494
495 if (err == 0) {
496 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
497
498 if (likely(mv == NULL)) {
499 binaryfunc slot = mv->nb_multiply;
500
501 if (likely(slot != NULL)) {
502 PyObject *x = slot(coerced1, coerced2);
503
504 Py_DECREF(coerced1);
505 Py_DECREF(coerced2);
506
507 obj_result = x;
508 goto exit_inplace_result_object;
509 }
510 }
511
512 // nb_coerce took a reference.
513 Py_DECREF(coerced1);
514 Py_DECREF(coerced2);
515 }
516 }
517 }
518#endif
519
520 {
521 // No sequence repeat slot sq_repeat available for this type.
522 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
523 }
524 // Special case for "*", also work with sequence repeat from right argument.
525 if (true) {
526 ssizeargfunc sq_slot = type2->tp_as_sequence != NULL ? type2->tp_as_sequence->sq_repeat : NULL;
527
528 if (sq_slot != NULL) {
529 PyObject *result = SEQUENCE_REPEAT(sq_slot, operand2, *operand1);
530
531 obj_result = result;
532 goto exit_inplace_result_object;
533 }
534 }
535
536 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and '%s'", type2->tp_name);
537 goto exit_inplace_exception;
538 }
539
540exit_inplace_result_object:
541 if (unlikely(obj_result == NULL)) {
542 return false;
543 }
544
545 // We got an object handed, that we have to release.
546 Py_DECREF(*operand1);
547
548 // That's our return value then. As we use a dedicated variable, it's
549 // OK that way.
550 *operand1 = obj_result;
551
552 return true;
553
554exit_inplace_exception:
555 return false;
556}
557static inline bool _INPLACE_OPERATION_MULT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
558 assert(operand1); // Pointer must be non-null.
559
560 CHECK_OBJECT(*operand1);
561 assert(PyInt_CheckExact(*operand1));
562 CHECK_OBJECT(operand2);
563
564 PyTypeObject *type2 = Py_TYPE(operand2);
565
566 if (&PyInt_Type == type2) {
567 // return _BINARY_OPERATION_MULT_INT_INT_INPLACE(operand1, operand2);
568
569 // Not every code path will make use of all possible results.
570#if defined(_MSC_VER)
571#pragma warning(push)
572#pragma warning(disable : 4101)
573#endif
574 NUITKA_MAY_BE_UNUSED bool cbool_result;
575 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
576 NUITKA_MAY_BE_UNUSED long clong_result;
577 NUITKA_MAY_BE_UNUSED double cfloat_result;
578#if defined(_MSC_VER)
579#pragma warning(pop)
580#endif
581
582 CHECK_OBJECT(*operand1);
583 assert(PyInt_CheckExact(*operand1));
584 CHECK_OBJECT(operand2);
585 assert(PyInt_CheckExact(operand2));
586
587 const long a = PyInt_AS_LONG(*operand1);
588 const long b = PyInt_AS_LONG(operand2);
589
590 const long longprod = (long)((unsigned long)a * b);
591 const double doubleprod = (double)a * (double)b;
592 const double doubled_longprod = (double)longprod;
593
594 if (likely(doubled_longprod == doubleprod)) {
595 clong_result = longprod;
596 goto exit_result_ok_clong;
597 } else {
598 const double diff = doubled_longprod - doubleprod;
599 const double absdiff = diff >= 0.0 ? diff : -diff;
600 const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod;
601
602 if (likely(32.0 * absdiff <= absprod)) {
603 clong_result = longprod;
604 goto exit_result_ok_clong;
605 }
606 }
607
608 {
609 PyObject *operand1_object = *operand1;
610 PyObject *operand2_object = operand2;
611
612 PyObject *r = PyLong_Type.tp_as_number->nb_multiply(operand1_object, operand2_object);
613 assert(r != Py_NotImplemented);
614
615 obj_result = r;
616 goto exit_result_object;
617 }
618
619 exit_result_ok_clong:
620
621 // We got an object handed, that we have to release.
622 Py_DECREF(*operand1);
623
624 // That's our return value then. As we use a dedicated variable, it's
625 // OK that way.
626 *operand1 = Nuitka_PyInt_FromLong(clong_result);
627 goto exit_result_ok;
628
629 exit_result_object:
630 if (unlikely(obj_result == NULL)) {
631 goto exit_result_exception;
632 }
633 // We got an object handed, that we have to release.
634 Py_DECREF(*operand1);
635
636 *operand1 = obj_result;
637 goto exit_result_ok;
638
639 exit_result_ok:
640 return true;
641
642 exit_result_exception:
643 return false;
644 }
645
646 return __INPLACE_OPERATION_MULT_INT_OBJECT(operand1, operand2);
647}
648
649bool INPLACE_OPERATION_MULT_INT_OBJECT(PyObject **operand1, PyObject *operand2) {
650 return _INPLACE_OPERATION_MULT_INT_OBJECT(operand1, operand2);
651}
652#endif
653
654/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LONG" to Python2 'long', Python3 'int'. */
655static inline bool _INPLACE_OPERATION_MULT_LONG_LONG(PyObject **operand1, PyObject *operand2) {
656 assert(operand1); // Pointer must be non-null.
657
658 CHECK_OBJECT(*operand1);
659 assert(PyLong_CheckExact(*operand1));
660 CHECK_OBJECT(operand2);
661 assert(PyLong_CheckExact(operand2));
662
663 // Not every code path will make use of all possible results.
664#if defined(_MSC_VER)
665#pragma warning(push)
666#pragma warning(disable : 4101)
667#endif
668 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
669 NUITKA_MAY_BE_UNUSED long clong_result;
670#if defined(_MSC_VER)
671#pragma warning(pop)
672#endif
673
674 PyObject *x = PyLong_Type.tp_as_number->nb_multiply(*operand1, operand2);
675 assert(x != Py_NotImplemented);
676
677 obj_result = x;
678 goto exit_result_object;
679
680exit_result_object:
681 if (unlikely(obj_result == NULL)) {
682 goto exit_result_exception;
683 }
684 // We got an object handed, that we have to release.
685 Py_DECREF(*operand1);
686 *operand1 = obj_result;
687 goto exit_result_ok;
688
689exit_result_ok:
690 return true;
691
692exit_result_exception:
693 return false;
694}
695
696bool INPLACE_OPERATION_MULT_LONG_LONG(PyObject **operand1, PyObject *operand2) {
697 return _INPLACE_OPERATION_MULT_LONG_LONG(operand1, operand2);
698}
699
700/* Code referring to "OBJECT" corresponds to any Python object and "LONG" to Python2 'long', Python3 'int'. */
701static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
702 PyTypeObject *type1 = Py_TYPE(*operand1);
703
704#if defined(_MSC_VER)
705#pragma warning(push)
706#pragma warning(disable : 4101)
707#endif
708 NUITKA_MAY_BE_UNUSED bool cbool_result;
709 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
710#if defined(_MSC_VER)
711#pragma warning(pop)
712#endif
713
714 binaryfunc islot =
715 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_multiply : NULL;
716
717 if (islot != NULL) {
718 PyObject *x = islot(*operand1, operand2);
719
720 if (x != Py_NotImplemented) {
721 obj_result = x;
722 goto exit_inplace_result_object;
723 }
724
725 Py_DECREF_IMMORTAL(x);
726 }
727
728 {
729 binaryfunc slot1 =
730 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_multiply : NULL;
731 binaryfunc slot2 = NULL;
732
733 if (!(type1 == &PyLong_Type)) {
734 // Different types, need to consider second value slot.
735
736 slot2 = PyLong_Type.tp_as_number->nb_multiply;
737
738 if (slot1 == slot2) {
739 slot2 = NULL;
740 }
741 }
742
743 if (slot1 != NULL) {
744 PyObject *x = slot1(*operand1, operand2);
745
746 if (x != Py_NotImplemented) {
747 obj_result = x;
748 goto exit_inplace_result_object;
749 }
750
751 Py_DECREF_IMMORTAL(x);
752 }
753
754 if (slot2 != NULL) {
755 PyObject *x = slot2(*operand1, operand2);
756
757 if (x != Py_NotImplemented) {
758 obj_result = x;
759 goto exit_inplace_result_object;
760 }
761
762 Py_DECREF_IMMORTAL(x);
763 }
764
765#if PYTHON_VERSION < 0x300
766 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
767 coercion c1 =
768 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
769
770 if (c1 != NULL) {
771 PyObject *coerced1 = *operand1;
772 PyObject *coerced2 = operand2;
773
774 int err = c1(&coerced1, &coerced2);
775
776 if (unlikely(err < 0)) {
777 goto exit_inplace_exception;
778 }
779
780 if (err == 0) {
781 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
782
783 if (likely(mv == NULL)) {
784 binaryfunc slot = mv->nb_multiply;
785
786 if (likely(slot != NULL)) {
787 PyObject *x = slot(coerced1, coerced2);
788
789 Py_DECREF(coerced1);
790 Py_DECREF(coerced2);
791
792 obj_result = x;
793 goto exit_inplace_result_object;
794 }
795 }
796
797 // nb_coerce took a reference.
798 Py_DECREF(coerced1);
799 Py_DECREF(coerced2);
800 }
801 }
802 coercion c2 = PyLong_Type.tp_as_number->nb_coerce;
803
804 if (c2 != NULL) {
805 PyObject *coerced1 = *operand1;
806 PyObject *coerced2 = operand2;
807
808 int err = c2(&coerced2, &coerced1);
809
810 if (unlikely(err < 0)) {
811 goto exit_inplace_exception;
812 }
813
814 if (err == 0) {
815 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
816
817 if (likely(mv == NULL)) {
818 binaryfunc slot = mv->nb_multiply;
819
820 if (likely(slot != NULL)) {
821 PyObject *x = slot(coerced1, coerced2);
822
823 Py_DECREF(coerced1);
824 Py_DECREF(coerced2);
825
826 obj_result = x;
827 goto exit_inplace_result_object;
828 }
829 }
830
831 // nb_coerce took a reference.
832 Py_DECREF(coerced1);
833 Py_DECREF(coerced2);
834 }
835 }
836 }
837#endif
838
839 {
840 // Special case for "+" and "*", also works as sequence concat/repeat.
841 ssizeargfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_inplace_repeat : NULL;
842 if (sq_slot == NULL) {
843 sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_repeat : NULL;
844 }
845
846 if (sq_slot != NULL) {
847 PyObject *result = SEQUENCE_REPEAT(sq_slot, *operand1, operand2);
848
849 obj_result = result;
850 goto exit_inplace_result_object;
851 }
852 }
853 // No sequence repeat slot sq_repeat available for this type.
854
855#if PYTHON_VERSION < 0x300
856 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: '%s' and 'long'", type1->tp_name);
857#else
858 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: '%s' and 'int'", type1->tp_name);
859#endif
860 goto exit_inplace_exception;
861 }
862
863exit_inplace_result_object:
864 if (unlikely(obj_result == NULL)) {
865 return false;
866 }
867
868 // We got an object handed, that we have to release.
869 Py_DECREF(*operand1);
870
871 // That's our return value then. As we use a dedicated variable, it's
872 // OK that way.
873 *operand1 = obj_result;
874
875 return true;
876
877exit_inplace_exception:
878 return false;
879}
880static inline bool _INPLACE_OPERATION_MULT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
881 assert(operand1); // Pointer must be non-null.
882
883 CHECK_OBJECT(*operand1);
884 CHECK_OBJECT(operand2);
885 assert(PyLong_CheckExact(operand2));
886
887 PyTypeObject *type1 = Py_TYPE(*operand1);
888
889 if (type1 == &PyLong_Type) {
890 // return _BINARY_OPERATION_MULT_LONG_LONG_INPLACE(operand1, operand2);
891
892 // Not every code path will make use of all possible results.
893#if defined(_MSC_VER)
894#pragma warning(push)
895#pragma warning(disable : 4101)
896#endif
897 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
898 NUITKA_MAY_BE_UNUSED long clong_result;
899#if defined(_MSC_VER)
900#pragma warning(pop)
901#endif
902
903 PyObject *x = PyLong_Type.tp_as_number->nb_multiply(*operand1, operand2);
904 assert(x != Py_NotImplemented);
905
906 obj_result = x;
907 goto exit_result_object;
908
909 exit_result_object:
910 if (unlikely(obj_result == NULL)) {
911 goto exit_result_exception;
912 }
913 // We got an object handed, that we have to release.
914 Py_DECREF(*operand1);
915 *operand1 = obj_result;
916 goto exit_result_ok;
917
918 exit_result_ok:
919 return true;
920
921 exit_result_exception:
922 return false;
923 }
924
925 return __INPLACE_OPERATION_MULT_OBJECT_LONG(operand1, operand2);
926}
927
928bool INPLACE_OPERATION_MULT_OBJECT_LONG(PyObject **operand1, PyObject *operand2) {
929 return _INPLACE_OPERATION_MULT_OBJECT_LONG(operand1, operand2);
930}
931
932/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "OBJECT" to any Python object. */
933static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
934 PyTypeObject *type2 = Py_TYPE(operand2);
935
936#if defined(_MSC_VER)
937#pragma warning(push)
938#pragma warning(disable : 4101)
939#endif
940 NUITKA_MAY_BE_UNUSED bool cbool_result;
941 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
942#if defined(_MSC_VER)
943#pragma warning(pop)
944#endif
945
946 // No inplace number slot nb_inplace_multiply available for this type.
947
948 {
949 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_multiply;
950 binaryfunc slot2 = NULL;
951
952 if (!(&PyLong_Type == type2)) {
953 // Different types, need to consider second value slot.
954
955 slot2 =
956 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
957
958 if (slot1 == slot2) {
959 slot2 = NULL;
960 }
961 }
962
963 if (slot1 != NULL) {
964 if (slot2 != NULL) {
965 if (Nuitka_Type_IsSubtype(type2, &PyLong_Type)) {
966 PyObject *x = slot2(*operand1, operand2);
967
968 if (x != Py_NotImplemented) {
969 obj_result = x;
970 goto exit_inplace_result_object;
971 }
972
973 Py_DECREF_IMMORTAL(x);
974 slot2 = NULL;
975 }
976 }
977
978 PyObject *x = slot1(*operand1, operand2);
979
980 if (x != Py_NotImplemented) {
981 obj_result = x;
982 goto exit_inplace_result_object;
983 }
984
985 Py_DECREF_IMMORTAL(x);
986 }
987
988 if (slot2 != NULL) {
989 PyObject *x = slot2(*operand1, operand2);
990
991 if (x != Py_NotImplemented) {
992 obj_result = x;
993 goto exit_inplace_result_object;
994 }
995
996 Py_DECREF_IMMORTAL(x);
997 }
998
999#if PYTHON_VERSION < 0x300
1000 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1001 coercion c1 = PyLong_Type.tp_as_number->nb_coerce;
1002
1003 if (c1 != NULL) {
1004 PyObject *coerced1 = *operand1;
1005 PyObject *coerced2 = operand2;
1006
1007 int err = c1(&coerced1, &coerced2);
1008
1009 if (unlikely(err < 0)) {
1010 goto exit_inplace_exception;
1011 }
1012
1013 if (err == 0) {
1014 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1015
1016 if (likely(mv == NULL)) {
1017 binaryfunc slot = mv->nb_multiply;
1018
1019 if (likely(slot != NULL)) {
1020 PyObject *x = slot(coerced1, coerced2);
1021
1022 Py_DECREF(coerced1);
1023 Py_DECREF(coerced2);
1024
1025 obj_result = x;
1026 goto exit_inplace_result_object;
1027 }
1028 }
1029
1030 // nb_coerce took a reference.
1031 Py_DECREF(coerced1);
1032 Py_DECREF(coerced2);
1033 }
1034 }
1035 coercion c2 =
1036 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1037
1038 if (c2 != NULL) {
1039 PyObject *coerced1 = *operand1;
1040 PyObject *coerced2 = operand2;
1041
1042 int err = c2(&coerced2, &coerced1);
1043
1044 if (unlikely(err < 0)) {
1045 goto exit_inplace_exception;
1046 }
1047
1048 if (err == 0) {
1049 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1050
1051 if (likely(mv == NULL)) {
1052 binaryfunc slot = mv->nb_multiply;
1053
1054 if (likely(slot != NULL)) {
1055 PyObject *x = slot(coerced1, coerced2);
1056
1057 Py_DECREF(coerced1);
1058 Py_DECREF(coerced2);
1059
1060 obj_result = x;
1061 goto exit_inplace_result_object;
1062 }
1063 }
1064
1065 // nb_coerce took a reference.
1066 Py_DECREF(coerced1);
1067 Py_DECREF(coerced2);
1068 }
1069 }
1070 }
1071#endif
1072
1073 {
1074 // No sequence repeat slot sq_repeat available for this type.
1075 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1076 }
1077 // Special case for "*", also work with sequence repeat from right argument.
1078 if (true) {
1079 ssizeargfunc sq_slot = type2->tp_as_sequence != NULL ? type2->tp_as_sequence->sq_repeat : NULL;
1080
1081 if (sq_slot != NULL) {
1082 PyObject *result = SEQUENCE_REPEAT(sq_slot, operand2, *operand1);
1083
1084 obj_result = result;
1085 goto exit_inplace_result_object;
1086 }
1087 }
1088
1089#if PYTHON_VERSION < 0x300
1090 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and '%s'", type2->tp_name);
1091#else
1092 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and '%s'", type2->tp_name);
1093#endif
1094 goto exit_inplace_exception;
1095 }
1096
1097exit_inplace_result_object:
1098 if (unlikely(obj_result == NULL)) {
1099 return false;
1100 }
1101
1102 // We got an object handed, that we have to release.
1103 Py_DECREF(*operand1);
1104
1105 // That's our return value then. As we use a dedicated variable, it's
1106 // OK that way.
1107 *operand1 = obj_result;
1108
1109 return true;
1110
1111exit_inplace_exception:
1112 return false;
1113}
1114static inline bool _INPLACE_OPERATION_MULT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
1115 assert(operand1); // Pointer must be non-null.
1116
1117 CHECK_OBJECT(*operand1);
1118 assert(PyLong_CheckExact(*operand1));
1119 CHECK_OBJECT(operand2);
1120
1121 PyTypeObject *type2 = Py_TYPE(operand2);
1122
1123 if (&PyLong_Type == type2) {
1124 // return _BINARY_OPERATION_MULT_LONG_LONG_INPLACE(operand1, operand2);
1125
1126 // Not every code path will make use of all possible results.
1127#if defined(_MSC_VER)
1128#pragma warning(push)
1129#pragma warning(disable : 4101)
1130#endif
1131 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1132 NUITKA_MAY_BE_UNUSED long clong_result;
1133#if defined(_MSC_VER)
1134#pragma warning(pop)
1135#endif
1136
1137 PyObject *x = PyLong_Type.tp_as_number->nb_multiply(*operand1, operand2);
1138 assert(x != Py_NotImplemented);
1139
1140 obj_result = x;
1141 goto exit_result_object;
1142
1143 exit_result_object:
1144 if (unlikely(obj_result == NULL)) {
1145 goto exit_result_exception;
1146 }
1147 // We got an object handed, that we have to release.
1148 Py_DECREF(*operand1);
1149 *operand1 = obj_result;
1150 goto exit_result_ok;
1151
1152 exit_result_ok:
1153 return true;
1154
1155 exit_result_exception:
1156 return false;
1157 }
1158
1159 return __INPLACE_OPERATION_MULT_LONG_OBJECT(operand1, operand2);
1160}
1161
1162bool INPLACE_OPERATION_MULT_LONG_OBJECT(PyObject **operand1, PyObject *operand2) {
1163 return _INPLACE_OPERATION_MULT_LONG_OBJECT(operand1, operand2);
1164}
1165
1166/* Code referring to "FLOAT" corresponds to Python 'float' and "FLOAT" to Python 'float'. */
1167static inline bool _INPLACE_OPERATION_MULT_FLOAT_FLOAT(PyObject **operand1, PyObject *operand2) {
1168 assert(operand1); // Pointer must be non-null.
1169
1170 CHECK_OBJECT(*operand1);
1171 assert(PyFloat_CheckExact(*operand1));
1172 CHECK_OBJECT(operand2);
1173 assert(PyFloat_CheckExact(operand2));
1174
1175#if defined(_MSC_VER)
1176#pragma warning(push)
1177#pragma warning(disable : 4101)
1178#endif
1179 // Not every code path will make use of all possible results.
1180 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1181 NUITKA_MAY_BE_UNUSED long clong_result;
1182 NUITKA_MAY_BE_UNUSED double cfloat_result;
1183#if defined(_MSC_VER)
1184#pragma warning(pop)
1185#endif
1186
1187 CHECK_OBJECT(*operand1);
1188 assert(PyFloat_CheckExact(*operand1));
1189 CHECK_OBJECT(operand2);
1190 assert(PyFloat_CheckExact(operand2));
1191
1192 const double a = PyFloat_AS_DOUBLE(*operand1);
1193 const double b = PyFloat_AS_DOUBLE(operand2);
1194
1195 double r = a * b;
1196
1197 cfloat_result = r;
1198 goto exit_result_ok_cfloat;
1199
1200exit_result_ok_cfloat:
1201 if (Py_REFCNT(*operand1) == 1) {
1202 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1203 } else {
1204 // We got an object handed, that we have to release.
1205 Py_DECREF(*operand1);
1206
1207 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1208 }
1209 goto exit_result_ok;
1210
1211exit_result_ok:
1212 return true;
1213}
1214
1215bool INPLACE_OPERATION_MULT_FLOAT_FLOAT(PyObject **operand1, PyObject *operand2) {
1216 return _INPLACE_OPERATION_MULT_FLOAT_FLOAT(operand1, operand2);
1217}
1218
1219/* Code referring to "OBJECT" corresponds to any Python object and "FLOAT" to Python 'float'. */
1220static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1221 PyTypeObject *type1 = Py_TYPE(*operand1);
1222
1223#if defined(_MSC_VER)
1224#pragma warning(push)
1225#pragma warning(disable : 4101)
1226#endif
1227 NUITKA_MAY_BE_UNUSED bool cbool_result;
1228 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1229#if defined(_MSC_VER)
1230#pragma warning(pop)
1231#endif
1232
1233 binaryfunc islot =
1234 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_multiply : NULL;
1235
1236 if (islot != NULL) {
1237 PyObject *x = islot(*operand1, operand2);
1238
1239 if (x != Py_NotImplemented) {
1240 obj_result = x;
1241 goto exit_inplace_result_object;
1242 }
1243
1244 Py_DECREF_IMMORTAL(x);
1245 }
1246
1247 {
1248 binaryfunc slot1 =
1249 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_multiply : NULL;
1250 binaryfunc slot2 = NULL;
1251
1252 if (!(type1 == &PyFloat_Type)) {
1253 // Different types, need to consider second value slot.
1254
1255 slot2 = PyFloat_Type.tp_as_number->nb_multiply;
1256
1257 if (slot1 == slot2) {
1258 slot2 = NULL;
1259 }
1260 }
1261
1262 if (slot1 != NULL) {
1263 PyObject *x = slot1(*operand1, operand2);
1264
1265 if (x != Py_NotImplemented) {
1266 obj_result = x;
1267 goto exit_inplace_result_object;
1268 }
1269
1270 Py_DECREF_IMMORTAL(x);
1271 }
1272
1273 if (slot2 != NULL) {
1274 PyObject *x = slot2(*operand1, operand2);
1275
1276 if (x != Py_NotImplemented) {
1277 obj_result = x;
1278 goto exit_inplace_result_object;
1279 }
1280
1281 Py_DECREF_IMMORTAL(x);
1282 }
1283
1284#if PYTHON_VERSION < 0x300
1285 if (!NEW_STYLE_NUMBER_TYPE(type1) || !1) {
1286 coercion c1 =
1287 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
1288
1289 if (c1 != NULL) {
1290 PyObject *coerced1 = *operand1;
1291 PyObject *coerced2 = operand2;
1292
1293 int err = c1(&coerced1, &coerced2);
1294
1295 if (unlikely(err < 0)) {
1296 goto exit_inplace_exception;
1297 }
1298
1299 if (err == 0) {
1300 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1301
1302 if (likely(mv == NULL)) {
1303 binaryfunc slot = mv->nb_multiply;
1304
1305 if (likely(slot != NULL)) {
1306 PyObject *x = slot(coerced1, coerced2);
1307
1308 Py_DECREF(coerced1);
1309 Py_DECREF(coerced2);
1310
1311 obj_result = x;
1312 goto exit_inplace_result_object;
1313 }
1314 }
1315
1316 // nb_coerce took a reference.
1317 Py_DECREF(coerced1);
1318 Py_DECREF(coerced2);
1319 }
1320 }
1321 coercion c2 = PyFloat_Type.tp_as_number->nb_coerce;
1322
1323 if (c2 != NULL) {
1324 PyObject *coerced1 = *operand1;
1325 PyObject *coerced2 = operand2;
1326
1327 int err = c2(&coerced2, &coerced1);
1328
1329 if (unlikely(err < 0)) {
1330 goto exit_inplace_exception;
1331 }
1332
1333 if (err == 0) {
1334 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1335
1336 if (likely(mv == NULL)) {
1337 binaryfunc slot = mv->nb_multiply;
1338
1339 if (likely(slot != NULL)) {
1340 PyObject *x = slot(coerced1, coerced2);
1341
1342 Py_DECREF(coerced1);
1343 Py_DECREF(coerced2);
1344
1345 obj_result = x;
1346 goto exit_inplace_result_object;
1347 }
1348 }
1349
1350 // nb_coerce took a reference.
1351 Py_DECREF(coerced1);
1352 Py_DECREF(coerced2);
1353 }
1354 }
1355 }
1356#endif
1357
1358 {
1359 // Special case for "+" and "*", also works as sequence concat/repeat.
1360 ssizeargfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_inplace_repeat : NULL;
1361 if (sq_slot == NULL) {
1362 sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_repeat : NULL;
1363 }
1364
1365 if (sq_slot != NULL) {
1366 PyObject *result = SEQUENCE_REPEAT(sq_slot, *operand1, operand2);
1367
1368 obj_result = result;
1369 goto exit_inplace_result_object;
1370 }
1371 }
1372 // No sequence repeat slot sq_repeat available for this type.
1373
1374 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: '%s' and 'float'", type1->tp_name);
1375 goto exit_inplace_exception;
1376 }
1377
1378exit_inplace_result_object:
1379 if (unlikely(obj_result == NULL)) {
1380 return false;
1381 }
1382
1383 // We got an object handed, that we have to release.
1384 Py_DECREF(*operand1);
1385
1386 // That's our return value then. As we use a dedicated variable, it's
1387 // OK that way.
1388 *operand1 = obj_result;
1389
1390 return true;
1391
1392exit_inplace_exception:
1393 return false;
1394}
1395static inline bool _INPLACE_OPERATION_MULT_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1396 assert(operand1); // Pointer must be non-null.
1397
1398 CHECK_OBJECT(*operand1);
1399 CHECK_OBJECT(operand2);
1400 assert(PyFloat_CheckExact(operand2));
1401
1402 PyTypeObject *type1 = Py_TYPE(*operand1);
1403
1404 if (type1 == &PyFloat_Type) {
1405 // return _BINARY_OPERATION_MULT_FLOAT_FLOAT_INPLACE(operand1, operand2);
1406
1407#if defined(_MSC_VER)
1408#pragma warning(push)
1409#pragma warning(disable : 4101)
1410#endif
1411 // Not every code path will make use of all possible results.
1412 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1413 NUITKA_MAY_BE_UNUSED long clong_result;
1414 NUITKA_MAY_BE_UNUSED double cfloat_result;
1415#if defined(_MSC_VER)
1416#pragma warning(pop)
1417#endif
1418
1419 CHECK_OBJECT(*operand1);
1420 assert(PyFloat_CheckExact(*operand1));
1421 CHECK_OBJECT(operand2);
1422 assert(PyFloat_CheckExact(operand2));
1423
1424 const double a = PyFloat_AS_DOUBLE(*operand1);
1425 const double b = PyFloat_AS_DOUBLE(operand2);
1426
1427 double r = a * b;
1428
1429 cfloat_result = r;
1430 goto exit_result_ok_cfloat;
1431
1432 exit_result_ok_cfloat:
1433 if (Py_REFCNT(*operand1) == 1) {
1434 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1435 } else {
1436 // We got an object handed, that we have to release.
1437 Py_DECREF(*operand1);
1438
1439 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1440 }
1441 goto exit_result_ok;
1442
1443 exit_result_ok:
1444 return true;
1445 }
1446
1447 return __INPLACE_OPERATION_MULT_OBJECT_FLOAT(operand1, operand2);
1448}
1449
1450bool INPLACE_OPERATION_MULT_OBJECT_FLOAT(PyObject **operand1, PyObject *operand2) {
1451 return _INPLACE_OPERATION_MULT_OBJECT_FLOAT(operand1, operand2);
1452}
1453
1454/* Code referring to "FLOAT" corresponds to Python 'float' and "OBJECT" to any Python object. */
1455static HEDLEY_NEVER_INLINE bool __INPLACE_OPERATION_MULT_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1456 PyTypeObject *type2 = Py_TYPE(operand2);
1457
1458#if defined(_MSC_VER)
1459#pragma warning(push)
1460#pragma warning(disable : 4101)
1461#endif
1462 NUITKA_MAY_BE_UNUSED bool cbool_result;
1463 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1464#if defined(_MSC_VER)
1465#pragma warning(pop)
1466#endif
1467
1468 // No inplace number slot nb_inplace_multiply available for this type.
1469
1470 {
1471 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_multiply;
1472 binaryfunc slot2 = NULL;
1473
1474 if (!(&PyFloat_Type == type2)) {
1475 // Different types, need to consider second value slot.
1476
1477 slot2 =
1478 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
1479
1480 if (slot1 == slot2) {
1481 slot2 = NULL;
1482 }
1483 }
1484
1485 if (slot1 != NULL) {
1486 if (slot2 != NULL) {
1487 if (Nuitka_Type_IsSubtype(type2, &PyFloat_Type)) {
1488 PyObject *x = slot2(*operand1, operand2);
1489
1490 if (x != Py_NotImplemented) {
1491 obj_result = x;
1492 goto exit_inplace_result_object;
1493 }
1494
1495 Py_DECREF_IMMORTAL(x);
1496 slot2 = NULL;
1497 }
1498 }
1499
1500 PyObject *x = slot1(*operand1, operand2);
1501
1502 if (x != Py_NotImplemented) {
1503 obj_result = x;
1504 goto exit_inplace_result_object;
1505 }
1506
1507 Py_DECREF_IMMORTAL(x);
1508 }
1509
1510 if (slot2 != NULL) {
1511 PyObject *x = slot2(*operand1, operand2);
1512
1513 if (x != Py_NotImplemented) {
1514 obj_result = x;
1515 goto exit_inplace_result_object;
1516 }
1517
1518 Py_DECREF_IMMORTAL(x);
1519 }
1520
1521#if PYTHON_VERSION < 0x300
1522 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
1523 coercion c1 = PyFloat_Type.tp_as_number->nb_coerce;
1524
1525 if (c1 != NULL) {
1526 PyObject *coerced1 = *operand1;
1527 PyObject *coerced2 = operand2;
1528
1529 int err = c1(&coerced1, &coerced2);
1530
1531 if (unlikely(err < 0)) {
1532 goto exit_inplace_exception;
1533 }
1534
1535 if (err == 0) {
1536 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1537
1538 if (likely(mv == NULL)) {
1539 binaryfunc slot = mv->nb_multiply;
1540
1541 if (likely(slot != NULL)) {
1542 PyObject *x = slot(coerced1, coerced2);
1543
1544 Py_DECREF(coerced1);
1545 Py_DECREF(coerced2);
1546
1547 obj_result = x;
1548 goto exit_inplace_result_object;
1549 }
1550 }
1551
1552 // nb_coerce took a reference.
1553 Py_DECREF(coerced1);
1554 Py_DECREF(coerced2);
1555 }
1556 }
1557 coercion c2 =
1558 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
1559
1560 if (c2 != NULL) {
1561 PyObject *coerced1 = *operand1;
1562 PyObject *coerced2 = operand2;
1563
1564 int err = c2(&coerced2, &coerced1);
1565
1566 if (unlikely(err < 0)) {
1567 goto exit_inplace_exception;
1568 }
1569
1570 if (err == 0) {
1571 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
1572
1573 if (likely(mv == NULL)) {
1574 binaryfunc slot = mv->nb_multiply;
1575
1576 if (likely(slot != NULL)) {
1577 PyObject *x = slot(coerced1, coerced2);
1578
1579 Py_DECREF(coerced1);
1580 Py_DECREF(coerced2);
1581
1582 obj_result = x;
1583 goto exit_inplace_result_object;
1584 }
1585 }
1586
1587 // nb_coerce took a reference.
1588 Py_DECREF(coerced1);
1589 Py_DECREF(coerced2);
1590 }
1591 }
1592 }
1593#endif
1594
1595 {
1596 // No sequence repeat slot sq_repeat available for this type.
1597 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1598 }
1599 // Special case for "*", also work with sequence repeat from right argument.
1600 if (true) {
1601 ssizeargfunc sq_slot = type2->tp_as_sequence != NULL ? type2->tp_as_sequence->sq_repeat : NULL;
1602
1603 if (sq_slot != NULL) {
1604 PyObject *result = SEQUENCE_REPEAT(sq_slot, operand2, *operand1);
1605
1606 obj_result = result;
1607 goto exit_inplace_result_object;
1608 }
1609 }
1610
1611 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'float' and '%s'", type2->tp_name);
1612 goto exit_inplace_exception;
1613 }
1614
1615exit_inplace_result_object:
1616 if (unlikely(obj_result == NULL)) {
1617 return false;
1618 }
1619
1620 // We got an object handed, that we have to release.
1621 Py_DECREF(*operand1);
1622
1623 // That's our return value then. As we use a dedicated variable, it's
1624 // OK that way.
1625 *operand1 = obj_result;
1626
1627 return true;
1628
1629exit_inplace_exception:
1630 return false;
1631}
1632static inline bool _INPLACE_OPERATION_MULT_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1633 assert(operand1); // Pointer must be non-null.
1634
1635 CHECK_OBJECT(*operand1);
1636 assert(PyFloat_CheckExact(*operand1));
1637 CHECK_OBJECT(operand2);
1638
1639 PyTypeObject *type2 = Py_TYPE(operand2);
1640
1641 if (&PyFloat_Type == type2) {
1642 // return _BINARY_OPERATION_MULT_FLOAT_FLOAT_INPLACE(operand1, operand2);
1643
1644#if defined(_MSC_VER)
1645#pragma warning(push)
1646#pragma warning(disable : 4101)
1647#endif
1648 // Not every code path will make use of all possible results.
1649 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1650 NUITKA_MAY_BE_UNUSED long clong_result;
1651 NUITKA_MAY_BE_UNUSED double cfloat_result;
1652#if defined(_MSC_VER)
1653#pragma warning(pop)
1654#endif
1655
1656 CHECK_OBJECT(*operand1);
1657 assert(PyFloat_CheckExact(*operand1));
1658 CHECK_OBJECT(operand2);
1659 assert(PyFloat_CheckExact(operand2));
1660
1661 const double a = PyFloat_AS_DOUBLE(*operand1);
1662 const double b = PyFloat_AS_DOUBLE(operand2);
1663
1664 double r = a * b;
1665
1666 cfloat_result = r;
1667 goto exit_result_ok_cfloat;
1668
1669 exit_result_ok_cfloat:
1670 if (Py_REFCNT(*operand1) == 1) {
1671 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
1672 } else {
1673 // We got an object handed, that we have to release.
1674 Py_DECREF(*operand1);
1675
1676 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
1677 }
1678 goto exit_result_ok;
1679
1680 exit_result_ok:
1681 return true;
1682 }
1683
1684 return __INPLACE_OPERATION_MULT_FLOAT_OBJECT(operand1, operand2);
1685}
1686
1687bool INPLACE_OPERATION_MULT_FLOAT_OBJECT(PyObject **operand1, PyObject *operand2) {
1688 return _INPLACE_OPERATION_MULT_FLOAT_OBJECT(operand1, operand2);
1689}
1690
1691/* Code referring to "FLOAT" corresponds to Python 'float' and "LONG" to Python2 'long', Python3 'int'. */
1692static inline bool _INPLACE_OPERATION_MULT_FLOAT_LONG(PyObject **operand1, PyObject *operand2) {
1693 assert(operand1); // Pointer must be non-null.
1694
1695 CHECK_OBJECT(*operand1);
1696 assert(PyFloat_CheckExact(*operand1));
1697 CHECK_OBJECT(operand2);
1698 assert(PyLong_CheckExact(operand2));
1699
1700#if defined(_MSC_VER)
1701#pragma warning(push)
1702#pragma warning(disable : 4101)
1703#endif
1704 NUITKA_MAY_BE_UNUSED bool cbool_result;
1705 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1706#if defined(_MSC_VER)
1707#pragma warning(pop)
1708#endif
1709
1710 // No inplace number slot nb_inplace_multiply available for this type.
1711
1712 {
1713 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_multiply;
1714 // Slot2 ignored on purpose, type1 takes precedence.
1715
1716 if (slot1 != NULL) {
1717 PyObject *x = slot1(*operand1, operand2);
1718
1719 if (x != Py_NotImplemented) {
1720 obj_result = x;
1721 goto exit_inplace_result_object;
1722 }
1723
1724 Py_DECREF_IMMORTAL(x);
1725 }
1726
1727 // Statically recognized that coercion is not possible with these types
1728
1729 {
1730 // No sequence repeat slot sq_repeat available for this type.
1731 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1732 }
1733 // No sequence repeat slot sq_repeat available for this type.
1734
1735#if PYTHON_VERSION < 0x300
1736 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'float' and 'long'");
1737#else
1738 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'float' and 'int'");
1739#endif
1740 goto exit_inplace_exception;
1741 }
1742
1743exit_inplace_result_object:
1744 if (unlikely(obj_result == NULL)) {
1745 return false;
1746 }
1747
1748 // We got an object handed, that we have to release.
1749 Py_DECREF(*operand1);
1750
1751 // That's our return value then. As we use a dedicated variable, it's
1752 // OK that way.
1753 *operand1 = obj_result;
1754
1755 return true;
1756
1757exit_inplace_exception:
1758 return false;
1759}
1760
1761bool INPLACE_OPERATION_MULT_FLOAT_LONG(PyObject **operand1, PyObject *operand2) {
1762 return _INPLACE_OPERATION_MULT_FLOAT_LONG(operand1, operand2);
1763}
1764
1765/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "FLOAT" to Python 'float'. */
1766static inline bool _INPLACE_OPERATION_MULT_LONG_FLOAT(PyObject **operand1, PyObject *operand2) {
1767 assert(operand1); // Pointer must be non-null.
1768
1769 CHECK_OBJECT(*operand1);
1770 assert(PyLong_CheckExact(*operand1));
1771 CHECK_OBJECT(operand2);
1772 assert(PyFloat_CheckExact(operand2));
1773
1774#if defined(_MSC_VER)
1775#pragma warning(push)
1776#pragma warning(disable : 4101)
1777#endif
1778 NUITKA_MAY_BE_UNUSED bool cbool_result;
1779 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1780#if defined(_MSC_VER)
1781#pragma warning(pop)
1782#endif
1783
1784 // No inplace number slot nb_inplace_multiply available for this type.
1785
1786 {
1787 // Slot1 ignored on purpose, type2 takes precedence.
1788 binaryfunc slot2 = NULL;
1789
1790 if (!(0)) {
1791 // Different types, need to consider second value slot.
1792
1793 slot2 = PyFloat_Type.tp_as_number->nb_multiply;
1794 }
1795
1796 if (slot2 != NULL) {
1797 PyObject *x = slot2(*operand1, operand2);
1798
1799 if (x != Py_NotImplemented) {
1800 obj_result = x;
1801 goto exit_inplace_result_object;
1802 }
1803
1804 Py_DECREF_IMMORTAL(x);
1805 }
1806
1807 // Statically recognized that coercion is not possible with these types
1808
1809 {
1810 // No sequence repeat slot sq_repeat available for this type.
1811 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1812 }
1813 // No sequence repeat slot sq_repeat available for this type.
1814
1815#if PYTHON_VERSION < 0x300
1816 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and 'float'");
1817#else
1818 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'float'");
1819#endif
1820 goto exit_inplace_exception;
1821 }
1822
1823exit_inplace_result_object:
1824 if (unlikely(obj_result == NULL)) {
1825 return false;
1826 }
1827
1828 // We got an object handed, that we have to release.
1829 Py_DECREF(*operand1);
1830
1831 // That's our return value then. As we use a dedicated variable, it's
1832 // OK that way.
1833 *operand1 = obj_result;
1834
1835 return true;
1836
1837exit_inplace_exception:
1838 return false;
1839}
1840
1841bool INPLACE_OPERATION_MULT_LONG_FLOAT(PyObject **operand1, PyObject *operand2) {
1842 return _INPLACE_OPERATION_MULT_LONG_FLOAT(operand1, operand2);
1843}
1844
1845#if PYTHON_VERSION < 0x300
1846/* Code referring to "FLOAT" corresponds to Python 'float' and "INT" to Python2 'int'. */
1847static inline bool _INPLACE_OPERATION_MULT_FLOAT_INT(PyObject **operand1, PyObject *operand2) {
1848 assert(operand1); // Pointer must be non-null.
1849
1850 CHECK_OBJECT(*operand1);
1851 assert(PyFloat_CheckExact(*operand1));
1852 CHECK_OBJECT(operand2);
1853 assert(PyInt_CheckExact(operand2));
1854
1855#if defined(_MSC_VER)
1856#pragma warning(push)
1857#pragma warning(disable : 4101)
1858#endif
1859 NUITKA_MAY_BE_UNUSED bool cbool_result;
1860 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1861#if defined(_MSC_VER)
1862#pragma warning(pop)
1863#endif
1864
1865 // No inplace number slot nb_inplace_multiply available for this type.
1866
1867 {
1868 binaryfunc slot1 = PyFloat_Type.tp_as_number->nb_multiply;
1869 // Slot2 ignored on purpose, type1 takes precedence.
1870
1871 if (slot1 != NULL) {
1872 PyObject *x = slot1(*operand1, operand2);
1873
1874 if (x != Py_NotImplemented) {
1875 obj_result = x;
1876 goto exit_inplace_result_object;
1877 }
1878
1879 Py_DECREF_IMMORTAL(x);
1880 }
1881
1882 // Statically recognized that coercion is not possible with these types
1883
1884 {
1885 // No sequence repeat slot sq_repeat available for this type.
1886 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1887 }
1888 // No sequence repeat slot sq_repeat available for this type.
1889
1890 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'float' and 'int'");
1891 goto exit_inplace_exception;
1892 }
1893
1894exit_inplace_result_object:
1895 if (unlikely(obj_result == NULL)) {
1896 return false;
1897 }
1898
1899 // We got an object handed, that we have to release.
1900 Py_DECREF(*operand1);
1901
1902 // That's our return value then. As we use a dedicated variable, it's
1903 // OK that way.
1904 *operand1 = obj_result;
1905
1906 return true;
1907
1908exit_inplace_exception:
1909 return false;
1910}
1911
1912bool INPLACE_OPERATION_MULT_FLOAT_INT(PyObject **operand1, PyObject *operand2) {
1913 return _INPLACE_OPERATION_MULT_FLOAT_INT(operand1, operand2);
1914}
1915#endif
1916
1917#if PYTHON_VERSION < 0x300
1918/* Code referring to "INT" corresponds to Python2 'int' and "FLOAT" to Python 'float'. */
1919static inline bool _INPLACE_OPERATION_MULT_INT_FLOAT(PyObject **operand1, PyObject *operand2) {
1920 assert(operand1); // Pointer must be non-null.
1921
1922 CHECK_OBJECT(*operand1);
1923 assert(PyInt_CheckExact(*operand1));
1924 CHECK_OBJECT(operand2);
1925 assert(PyFloat_CheckExact(operand2));
1926
1927#if defined(_MSC_VER)
1928#pragma warning(push)
1929#pragma warning(disable : 4101)
1930#endif
1931 NUITKA_MAY_BE_UNUSED bool cbool_result;
1932 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
1933#if defined(_MSC_VER)
1934#pragma warning(pop)
1935#endif
1936
1937 // No inplace number slot nb_inplace_multiply available for this type.
1938
1939 {
1940 // Slot1 ignored on purpose, type2 takes precedence.
1941 binaryfunc slot2 = NULL;
1942
1943 if (!(0)) {
1944 // Different types, need to consider second value slot.
1945
1946 slot2 = PyFloat_Type.tp_as_number->nb_multiply;
1947 }
1948
1949 if (slot2 != NULL) {
1950 PyObject *x = slot2(*operand1, operand2);
1951
1952 if (x != Py_NotImplemented) {
1953 obj_result = x;
1954 goto exit_inplace_result_object;
1955 }
1956
1957 Py_DECREF_IMMORTAL(x);
1958 }
1959
1960 // Statically recognized that coercion is not possible with these types
1961
1962 {
1963 // No sequence repeat slot sq_repeat available for this type.
1964 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
1965 }
1966 // No sequence repeat slot sq_repeat available for this type.
1967
1968 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'float'");
1969 goto exit_inplace_exception;
1970 }
1971
1972exit_inplace_result_object:
1973 if (unlikely(obj_result == NULL)) {
1974 return false;
1975 }
1976
1977 // We got an object handed, that we have to release.
1978 Py_DECREF(*operand1);
1979
1980 // That's our return value then. As we use a dedicated variable, it's
1981 // OK that way.
1982 *operand1 = obj_result;
1983
1984 return true;
1985
1986exit_inplace_exception:
1987 return false;
1988}
1989
1990bool INPLACE_OPERATION_MULT_INT_FLOAT(PyObject **operand1, PyObject *operand2) {
1991 return _INPLACE_OPERATION_MULT_INT_FLOAT(operand1, operand2);
1992}
1993#endif
1994
1995#if PYTHON_VERSION < 0x300
1996/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "INT" to Python2 'int'. */
1997static inline bool _INPLACE_OPERATION_MULT_LONG_INT(PyObject **operand1, PyObject *operand2) {
1998 assert(operand1); // Pointer must be non-null.
1999
2000 CHECK_OBJECT(*operand1);
2001 assert(PyLong_CheckExact(*operand1));
2002 CHECK_OBJECT(operand2);
2003 assert(PyInt_CheckExact(operand2));
2004
2005#if defined(_MSC_VER)
2006#pragma warning(push)
2007#pragma warning(disable : 4101)
2008#endif
2009 NUITKA_MAY_BE_UNUSED bool cbool_result;
2010 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2011#if defined(_MSC_VER)
2012#pragma warning(pop)
2013#endif
2014
2015 // No inplace number slot nb_inplace_multiply available for this type.
2016
2017 {
2018 binaryfunc slot1 = PyLong_Type.tp_as_number->nb_multiply;
2019 // Slot2 ignored on purpose, type1 takes precedence.
2020
2021 if (slot1 != NULL) {
2022 PyObject *x = slot1(*operand1, operand2);
2023
2024 if (x != Py_NotImplemented) {
2025 obj_result = x;
2026 goto exit_inplace_result_object;
2027 }
2028
2029 Py_DECREF_IMMORTAL(x);
2030 }
2031
2032 // Statically recognized that coercion is not possible with these types
2033
2034 {
2035 // No sequence repeat slot sq_repeat available for this type.
2036 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2037 }
2038 // No sequence repeat slot sq_repeat available for this type.
2039
2040 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and 'int'");
2041 goto exit_inplace_exception;
2042 }
2043
2044exit_inplace_result_object:
2045 if (unlikely(obj_result == NULL)) {
2046 return false;
2047 }
2048
2049 // We got an object handed, that we have to release.
2050 Py_DECREF(*operand1);
2051
2052 // That's our return value then. As we use a dedicated variable, it's
2053 // OK that way.
2054 *operand1 = obj_result;
2055
2056 return true;
2057
2058exit_inplace_exception:
2059 return false;
2060}
2061
2062bool INPLACE_OPERATION_MULT_LONG_INT(PyObject **operand1, PyObject *operand2) {
2063 return _INPLACE_OPERATION_MULT_LONG_INT(operand1, operand2);
2064}
2065#endif
2066
2067#if PYTHON_VERSION < 0x300
2068/* Code referring to "INT" corresponds to Python2 'int' and "LONG" to Python2 'long', Python3 'int'. */
2069static inline bool _INPLACE_OPERATION_MULT_INT_LONG(PyObject **operand1, PyObject *operand2) {
2070 assert(operand1); // Pointer must be non-null.
2071
2072 CHECK_OBJECT(*operand1);
2073 assert(PyInt_CheckExact(*operand1));
2074 CHECK_OBJECT(operand2);
2075 assert(PyLong_CheckExact(operand2));
2076
2077#if defined(_MSC_VER)
2078#pragma warning(push)
2079#pragma warning(disable : 4101)
2080#endif
2081 NUITKA_MAY_BE_UNUSED bool cbool_result;
2082 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2083#if defined(_MSC_VER)
2084#pragma warning(pop)
2085#endif
2086
2087 // No inplace number slot nb_inplace_multiply available for this type.
2088
2089 {
2090 // Slot1 ignored on purpose, type2 takes precedence.
2091 binaryfunc slot2 = NULL;
2092
2093 if (!(0)) {
2094 // Different types, need to consider second value slot.
2095
2096 slot2 = PyLong_Type.tp_as_number->nb_multiply;
2097 }
2098
2099 if (slot2 != NULL) {
2100 PyObject *x = slot2(*operand1, operand2);
2101
2102 if (x != Py_NotImplemented) {
2103 obj_result = x;
2104 goto exit_inplace_result_object;
2105 }
2106
2107 Py_DECREF_IMMORTAL(x);
2108 }
2109
2110 // Statically recognized that coercion is not possible with these types
2111
2112 {
2113 // No sequence repeat slot sq_repeat available for this type.
2114 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2115 }
2116 // No sequence repeat slot sq_repeat available for this type.
2117
2118 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'long'");
2119 goto exit_inplace_exception;
2120 }
2121
2122exit_inplace_result_object:
2123 if (unlikely(obj_result == NULL)) {
2124 return false;
2125 }
2126
2127 // We got an object handed, that we have to release.
2128 Py_DECREF(*operand1);
2129
2130 // That's our return value then. As we use a dedicated variable, it's
2131 // OK that way.
2132 *operand1 = obj_result;
2133
2134 return true;
2135
2136exit_inplace_exception:
2137 return false;
2138}
2139
2140bool INPLACE_OPERATION_MULT_INT_LONG(PyObject **operand1, PyObject *operand2) {
2141 return _INPLACE_OPERATION_MULT_INT_LONG(operand1, operand2);
2142}
2143#endif
2144
2145#if PYTHON_VERSION < 0x300
2146/* Code referring to "INT" corresponds to Python2 'int' and "CLONG" to C platform long value. */
2147static inline bool _INPLACE_OPERATION_MULT_INT_CLONG(PyObject **operand1, long operand2) {
2148 assert(operand1); // Pointer must be non-null.
2149
2150 CHECK_OBJECT(*operand1);
2151 assert(PyInt_CheckExact(*operand1));
2152
2153 // Not every code path will make use of all possible results.
2154#if defined(_MSC_VER)
2155#pragma warning(push)
2156#pragma warning(disable : 4101)
2157#endif
2158 NUITKA_MAY_BE_UNUSED bool cbool_result;
2159 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2160 NUITKA_MAY_BE_UNUSED long clong_result;
2161 NUITKA_MAY_BE_UNUSED double cfloat_result;
2162#if defined(_MSC_VER)
2163#pragma warning(pop)
2164#endif
2165
2166 CHECK_OBJECT(*operand1);
2167 assert(PyInt_CheckExact(*operand1));
2168
2169 const long a = PyInt_AS_LONG(*operand1);
2170 const long b = operand2;
2171
2172 const long longprod = (long)((unsigned long)a * b);
2173 const double doubleprod = (double)a * (double)b;
2174 const double doubled_longprod = (double)longprod;
2175
2176 if (likely(doubled_longprod == doubleprod)) {
2177 clong_result = longprod;
2178 goto exit_result_ok_clong;
2179 } else {
2180 const double diff = doubled_longprod - doubleprod;
2181 const double absdiff = diff >= 0.0 ? diff : -diff;
2182 const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod;
2183
2184 if (likely(32.0 * absdiff <= absprod)) {
2185 clong_result = longprod;
2186 goto exit_result_ok_clong;
2187 }
2188 }
2189
2190 {
2191 PyObject *operand1_object = *operand1;
2192 PyObject *operand2_object = Nuitka_PyLong_FromLong(operand2);
2193
2194 PyObject *r = PyLong_Type.tp_as_number->nb_multiply(operand1_object, operand2_object);
2195 assert(r != Py_NotImplemented);
2196
2197 Py_DECREF(operand2_object);
2198
2199 obj_result = r;
2200 goto exit_result_object;
2201 }
2202
2203exit_result_ok_clong:
2204
2205 // We got an object handed, that we have to release.
2206 Py_DECREF(*operand1);
2207
2208 // That's our return value then. As we use a dedicated variable, it's
2209 // OK that way.
2210 *operand1 = Nuitka_PyInt_FromLong(clong_result);
2211 goto exit_result_ok;
2212
2213exit_result_object:
2214 if (unlikely(obj_result == NULL)) {
2215 goto exit_result_exception;
2216 }
2217 // We got an object handed, that we have to release.
2218 Py_DECREF(*operand1);
2219
2220 *operand1 = obj_result;
2221 goto exit_result_ok;
2222
2223exit_result_ok:
2224 return true;
2225
2226exit_result_exception:
2227 return false;
2228}
2229
2230bool INPLACE_OPERATION_MULT_INT_CLONG(PyObject **operand1, long operand2) {
2231 return _INPLACE_OPERATION_MULT_INT_CLONG(operand1, operand2);
2232}
2233#endif
2234
2235/* Code referring to "FLOAT" corresponds to Python 'float' and "CFLOAT" to C platform float value. */
2236static inline bool _INPLACE_OPERATION_MULT_FLOAT_CFLOAT(PyObject **operand1, double operand2) {
2237 assert(operand1); // Pointer must be non-null.
2238
2239 CHECK_OBJECT(*operand1);
2240 assert(PyFloat_CheckExact(*operand1));
2241
2242#if defined(_MSC_VER)
2243#pragma warning(push)
2244#pragma warning(disable : 4101)
2245#endif
2246 // Not every code path will make use of all possible results.
2247 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2248 NUITKA_MAY_BE_UNUSED long clong_result;
2249 NUITKA_MAY_BE_UNUSED double cfloat_result;
2250#if defined(_MSC_VER)
2251#pragma warning(pop)
2252#endif
2253
2254 CHECK_OBJECT(*operand1);
2255 assert(PyFloat_CheckExact(*operand1));
2256
2257 const double a = PyFloat_AS_DOUBLE(*operand1);
2258 const double b = operand2;
2259
2260 double r = a * b;
2261
2262 cfloat_result = r;
2263 goto exit_result_ok_cfloat;
2264
2265exit_result_ok_cfloat:
2266 if (Py_REFCNT(*operand1) == 1) {
2267 PyFloat_SET_DOUBLE(*operand1, cfloat_result);
2268 } else {
2269 // We got an object handed, that we have to release.
2270 Py_DECREF(*operand1);
2271
2272 *operand1 = MAKE_FLOAT_FROM_DOUBLE(cfloat_result);
2273 }
2274 goto exit_result_ok;
2275
2276exit_result_ok:
2277 return true;
2278}
2279
2280bool INPLACE_OPERATION_MULT_FLOAT_CFLOAT(PyObject **operand1, double operand2) {
2281 return _INPLACE_OPERATION_MULT_FLOAT_CFLOAT(operand1, operand2);
2282}
2283
2284#if PYTHON_VERSION < 0x300
2285/* Code referring to "STR" corresponds to Python2 'str' and "INT" to Python2 'int'. */
2286static inline bool _INPLACE_OPERATION_MULT_STR_INT(PyObject **operand1, PyObject *operand2) {
2287 assert(operand1); // Pointer must be non-null.
2288
2289 CHECK_OBJECT(*operand1);
2290 assert(PyString_CheckExact(*operand1));
2291 CHECK_OBJECT(operand2);
2292 assert(PyInt_CheckExact(operand2));
2293
2294#if defined(_MSC_VER)
2295#pragma warning(push)
2296#pragma warning(disable : 4101)
2297#endif
2298 NUITKA_MAY_BE_UNUSED bool cbool_result;
2299 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2300#if defined(_MSC_VER)
2301#pragma warning(pop)
2302#endif
2303
2304 // No inplace number slot nb_inplace_multiply available for this type.
2305
2306 {
2307 // Slot2 ignored on purpose, type1 takes precedence.
2308
2309 // Statically recognized that coercion is not possible with these types
2310
2311 if (unlikely(!1)) {
2312 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
2313
2314 goto exit_inplace_exception;
2315 }
2316
2317 {
2318 PyObject *index_value = operand2;
2319
2320 {
2321 Py_ssize_t count = PyInt_AS_LONG(index_value);
2322 {
2323 ssizeargfunc repeatfunc = NULL;
2324 if (repeatfunc == NULL) {
2325 repeatfunc = PyString_Type.tp_as_sequence->sq_repeat;
2326 }
2327 PyObject *r = (*repeatfunc)(*operand1, count);
2328
2329 obj_result = r;
2330 goto exit_inplace_result_object;
2331 }
2332 }
2333 }
2334
2335 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
2336 }
2337
2338exit_inplace_result_object:
2339 if (unlikely(obj_result == NULL)) {
2340 return false;
2341 }
2342
2343 // We got an object handed, that we have to release.
2344 Py_DECREF(*operand1);
2345
2346 // That's our return value then. As we use a dedicated variable, it's
2347 // OK that way.
2348 *operand1 = obj_result;
2349
2350 return true;
2351
2352exit_inplace_exception:
2353 return false;
2354}
2355
2356bool INPLACE_OPERATION_MULT_STR_INT(PyObject **operand1, PyObject *operand2) {
2357 return _INPLACE_OPERATION_MULT_STR_INT(operand1, operand2);
2358}
2359#endif
2360
2361#if PYTHON_VERSION < 0x300
2362/* Code referring to "INT" corresponds to Python2 'int' and "STR" to Python2 'str'. */
2363static inline bool _INPLACE_OPERATION_MULT_INT_STR(PyObject **operand1, PyObject *operand2) {
2364 assert(operand1); // Pointer must be non-null.
2365
2366 CHECK_OBJECT(*operand1);
2367 assert(PyInt_CheckExact(*operand1));
2368 CHECK_OBJECT(operand2);
2369 assert(PyString_CheckExact(operand2));
2370
2371#if defined(_MSC_VER)
2372#pragma warning(push)
2373#pragma warning(disable : 4101)
2374#endif
2375 NUITKA_MAY_BE_UNUSED bool cbool_result;
2376 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2377#if defined(_MSC_VER)
2378#pragma warning(pop)
2379#endif
2380
2381 // No inplace number slot nb_inplace_multiply available for this type.
2382
2383 {
2384 // Slot1 ignored on purpose, type2 takes precedence.
2385
2386 // Statically recognized that coercion is not possible with these types
2387
2388 {
2389 // No sequence repeat slot sq_repeat available for this type.
2390 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2391 }
2392 if (true) {
2393 if (unlikely(!1)) {
2394 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
2395
2396 goto exit_inplace_exception;
2397 }
2398
2399 {
2400 PyObject *index_value = *operand1;
2401
2402 {
2403 Py_ssize_t count = PyInt_AS_LONG(index_value);
2404 {
2405 ssizeargfunc repeatfunc = NULL;
2406 if (repeatfunc == NULL) {
2407 repeatfunc = PyString_Type.tp_as_sequence->sq_repeat;
2408 }
2409 PyObject *r = (*repeatfunc)(operand2, count);
2410
2411 obj_result = r;
2412 goto exit_inplace_result_object;
2413 }
2414 }
2415 }
2416 }
2417
2418 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'str'");
2419 goto exit_inplace_exception;
2420 }
2421
2422exit_inplace_result_object:
2423 if (unlikely(obj_result == NULL)) {
2424 return false;
2425 }
2426
2427 // We got an object handed, that we have to release.
2428 Py_DECREF(*operand1);
2429
2430 // That's our return value then. As we use a dedicated variable, it's
2431 // OK that way.
2432 *operand1 = obj_result;
2433
2434 return true;
2435
2436exit_inplace_exception:
2437 return false;
2438}
2439
2440bool INPLACE_OPERATION_MULT_INT_STR(PyObject **operand1, PyObject *operand2) {
2441 return _INPLACE_OPERATION_MULT_INT_STR(operand1, operand2);
2442}
2443#endif
2444
2445#if PYTHON_VERSION < 0x300
2446/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "INT" to Python2 'int'. */
2447static inline bool _INPLACE_OPERATION_MULT_UNICODE_INT(PyObject **operand1, PyObject *operand2) {
2448 assert(operand1); // Pointer must be non-null.
2449
2450 CHECK_OBJECT(*operand1);
2451 assert(PyUnicode_CheckExact(*operand1));
2452 CHECK_OBJECT(operand2);
2453 assert(PyInt_CheckExact(operand2));
2454
2455#if defined(_MSC_VER)
2456#pragma warning(push)
2457#pragma warning(disable : 4101)
2458#endif
2459 NUITKA_MAY_BE_UNUSED bool cbool_result;
2460 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2461#if defined(_MSC_VER)
2462#pragma warning(pop)
2463#endif
2464
2465 // No inplace number slot nb_inplace_multiply available for this type.
2466
2467 {
2468 // Slot2 ignored on purpose, type1 takes precedence.
2469
2470 // Statically recognized that coercion is not possible with these types
2471
2472 if (unlikely(!1)) {
2473 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
2474
2475 goto exit_inplace_exception;
2476 }
2477
2478 {
2479 PyObject *index_value = operand2;
2480
2481 {
2482 Py_ssize_t count = PyInt_AS_LONG(index_value);
2483 {
2484 ssizeargfunc repeatfunc = NULL;
2485 if (repeatfunc == NULL) {
2486 repeatfunc = PyUnicode_Type.tp_as_sequence->sq_repeat;
2487 }
2488 PyObject *r = (*repeatfunc)(*operand1, count);
2489
2490 obj_result = r;
2491 goto exit_inplace_result_object;
2492 }
2493 }
2494 }
2495
2496 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
2497 }
2498
2499exit_inplace_result_object:
2500 if (unlikely(obj_result == NULL)) {
2501 return false;
2502 }
2503
2504 // We got an object handed, that we have to release.
2505 Py_DECREF(*operand1);
2506
2507 // That's our return value then. As we use a dedicated variable, it's
2508 // OK that way.
2509 *operand1 = obj_result;
2510
2511 return true;
2512
2513exit_inplace_exception:
2514 return false;
2515}
2516
2517bool INPLACE_OPERATION_MULT_UNICODE_INT(PyObject **operand1, PyObject *operand2) {
2518 return _INPLACE_OPERATION_MULT_UNICODE_INT(operand1, operand2);
2519}
2520#endif
2521
2522#if PYTHON_VERSION < 0x300
2523/* Code referring to "INT" corresponds to Python2 'int' and "UNICODE" to Python2 'unicode', Python3 'str'. */
2524static inline bool _INPLACE_OPERATION_MULT_INT_UNICODE(PyObject **operand1, PyObject *operand2) {
2525 assert(operand1); // Pointer must be non-null.
2526
2527 CHECK_OBJECT(*operand1);
2528 assert(PyInt_CheckExact(*operand1));
2529 CHECK_OBJECT(operand2);
2530 assert(PyUnicode_CheckExact(operand2));
2531
2532#if defined(_MSC_VER)
2533#pragma warning(push)
2534#pragma warning(disable : 4101)
2535#endif
2536 NUITKA_MAY_BE_UNUSED bool cbool_result;
2537 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2538#if defined(_MSC_VER)
2539#pragma warning(pop)
2540#endif
2541
2542 // No inplace number slot nb_inplace_multiply available for this type.
2543
2544 {
2545 // Slot1 ignored on purpose, type2 takes precedence.
2546
2547 // Statically recognized that coercion is not possible with these types
2548
2549 {
2550 // No sequence repeat slot sq_repeat available for this type.
2551 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2552 }
2553 if (true) {
2554 if (unlikely(!1)) {
2555 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
2556
2557 goto exit_inplace_exception;
2558 }
2559
2560 {
2561 PyObject *index_value = *operand1;
2562
2563 {
2564 Py_ssize_t count = PyInt_AS_LONG(index_value);
2565 {
2566 ssizeargfunc repeatfunc = NULL;
2567 if (repeatfunc == NULL) {
2568 repeatfunc = PyUnicode_Type.tp_as_sequence->sq_repeat;
2569 }
2570 PyObject *r = (*repeatfunc)(operand2, count);
2571
2572 obj_result = r;
2573 goto exit_inplace_result_object;
2574 }
2575 }
2576 }
2577 }
2578
2579 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'unicode'");
2580 goto exit_inplace_exception;
2581 }
2582
2583exit_inplace_result_object:
2584 if (unlikely(obj_result == NULL)) {
2585 return false;
2586 }
2587
2588 // We got an object handed, that we have to release.
2589 Py_DECREF(*operand1);
2590
2591 // That's our return value then. As we use a dedicated variable, it's
2592 // OK that way.
2593 *operand1 = obj_result;
2594
2595 return true;
2596
2597exit_inplace_exception:
2598 return false;
2599}
2600
2601bool INPLACE_OPERATION_MULT_INT_UNICODE(PyObject **operand1, PyObject *operand2) {
2602 return _INPLACE_OPERATION_MULT_INT_UNICODE(operand1, operand2);
2603}
2604#endif
2605
2606#if PYTHON_VERSION < 0x300
2607/* Code referring to "TUPLE" corresponds to Python 'tuple' and "INT" to Python2 'int'. */
2608static inline bool _INPLACE_OPERATION_MULT_TUPLE_INT(PyObject **operand1, PyObject *operand2) {
2609 assert(operand1); // Pointer must be non-null.
2610
2611 CHECK_OBJECT(*operand1);
2612 assert(PyTuple_CheckExact(*operand1));
2613 CHECK_OBJECT(operand2);
2614 assert(PyInt_CheckExact(operand2));
2615
2616#if defined(_MSC_VER)
2617#pragma warning(push)
2618#pragma warning(disable : 4101)
2619#endif
2620 NUITKA_MAY_BE_UNUSED bool cbool_result;
2621 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2622#if defined(_MSC_VER)
2623#pragma warning(pop)
2624#endif
2625
2626 // No inplace number slot nb_inplace_multiply available for this type.
2627
2628 {
2629 // Slot2 ignored on purpose, type1 takes precedence.
2630
2631 // Statically recognized that coercion is not possible with these types
2632
2633 if (unlikely(!1)) {
2634 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
2635
2636 goto exit_inplace_exception;
2637 }
2638
2639 {
2640 PyObject *index_value = operand2;
2641
2642 {
2643 Py_ssize_t count = PyInt_AS_LONG(index_value);
2644 {
2645 ssizeargfunc repeatfunc = NULL;
2646 if (repeatfunc == NULL) {
2647 repeatfunc = PyTuple_Type.tp_as_sequence->sq_repeat;
2648 }
2649 PyObject *r = (*repeatfunc)(*operand1, count);
2650
2651 obj_result = r;
2652 goto exit_inplace_result_object;
2653 }
2654 }
2655 }
2656
2657 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
2658 }
2659
2660exit_inplace_result_object:
2661 if (unlikely(obj_result == NULL)) {
2662 return false;
2663 }
2664
2665 // We got an object handed, that we have to release.
2666 Py_DECREF(*operand1);
2667
2668 // That's our return value then. As we use a dedicated variable, it's
2669 // OK that way.
2670 *operand1 = obj_result;
2671
2672 return true;
2673
2674exit_inplace_exception:
2675 return false;
2676}
2677
2678bool INPLACE_OPERATION_MULT_TUPLE_INT(PyObject **operand1, PyObject *operand2) {
2679 return _INPLACE_OPERATION_MULT_TUPLE_INT(operand1, operand2);
2680}
2681#endif
2682
2683#if PYTHON_VERSION < 0x300
2684/* Code referring to "INT" corresponds to Python2 'int' and "TUPLE" to Python 'tuple'. */
2685static inline bool _INPLACE_OPERATION_MULT_INT_TUPLE(PyObject **operand1, PyObject *operand2) {
2686 assert(operand1); // Pointer must be non-null.
2687
2688 CHECK_OBJECT(*operand1);
2689 assert(PyInt_CheckExact(*operand1));
2690 CHECK_OBJECT(operand2);
2691 assert(PyTuple_CheckExact(operand2));
2692
2693#if defined(_MSC_VER)
2694#pragma warning(push)
2695#pragma warning(disable : 4101)
2696#endif
2697 NUITKA_MAY_BE_UNUSED bool cbool_result;
2698 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2699#if defined(_MSC_VER)
2700#pragma warning(pop)
2701#endif
2702
2703 // No inplace number slot nb_inplace_multiply available for this type.
2704
2705 {
2706 // Slot1 ignored on purpose, type2 takes precedence.
2707
2708 // Statically recognized that coercion is not possible with these types
2709
2710 {
2711 // No sequence repeat slot sq_repeat available for this type.
2712 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2713 }
2714 if (true) {
2715 if (unlikely(!1)) {
2716 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
2717
2718 goto exit_inplace_exception;
2719 }
2720
2721 {
2722 PyObject *index_value = *operand1;
2723
2724 {
2725 Py_ssize_t count = PyInt_AS_LONG(index_value);
2726 {
2727 ssizeargfunc repeatfunc = NULL;
2728 if (repeatfunc == NULL) {
2729 repeatfunc = PyTuple_Type.tp_as_sequence->sq_repeat;
2730 }
2731 PyObject *r = (*repeatfunc)(operand2, count);
2732
2733 obj_result = r;
2734 goto exit_inplace_result_object;
2735 }
2736 }
2737 }
2738 }
2739
2740 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'tuple'");
2741 goto exit_inplace_exception;
2742 }
2743
2744exit_inplace_result_object:
2745 if (unlikely(obj_result == NULL)) {
2746 return false;
2747 }
2748
2749 // We got an object handed, that we have to release.
2750 Py_DECREF(*operand1);
2751
2752 // That's our return value then. As we use a dedicated variable, it's
2753 // OK that way.
2754 *operand1 = obj_result;
2755
2756 return true;
2757
2758exit_inplace_exception:
2759 return false;
2760}
2761
2762bool INPLACE_OPERATION_MULT_INT_TUPLE(PyObject **operand1, PyObject *operand2) {
2763 return _INPLACE_OPERATION_MULT_INT_TUPLE(operand1, operand2);
2764}
2765#endif
2766
2767#if PYTHON_VERSION < 0x300
2768/* Code referring to "LIST" corresponds to Python 'list' and "INT" to Python2 'int'. */
2769static inline bool _INPLACE_OPERATION_MULT_LIST_INT(PyObject **operand1, PyObject *operand2) {
2770 assert(operand1); // Pointer must be non-null.
2771
2772 CHECK_OBJECT(*operand1);
2773 assert(PyList_CheckExact(*operand1));
2774 CHECK_OBJECT(operand2);
2775 assert(PyInt_CheckExact(operand2));
2776
2777#if defined(_MSC_VER)
2778#pragma warning(push)
2779#pragma warning(disable : 4101)
2780#endif
2781 NUITKA_MAY_BE_UNUSED bool cbool_result;
2782 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2783#if defined(_MSC_VER)
2784#pragma warning(pop)
2785#endif
2786
2787 // No inplace number slot nb_inplace_multiply available for this type.
2788
2789 {
2790 // Slot2 ignored on purpose, type1 takes precedence.
2791
2792 // Statically recognized that coercion is not possible with these types
2793
2794 if (unlikely(!1)) {
2795 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
2796
2797 goto exit_inplace_exception;
2798 }
2799
2800 {
2801 PyObject *index_value = operand2;
2802
2803 {
2804 Py_ssize_t count = PyInt_AS_LONG(index_value);
2805 {
2806 ssizeargfunc repeatfunc = PyList_Type.tp_as_sequence->sq_inplace_repeat;
2807 if (repeatfunc == NULL) {
2808 repeatfunc = PyList_Type.tp_as_sequence->sq_repeat;
2809 }
2810 PyObject *r = (*repeatfunc)(*operand1, count);
2811
2812 obj_result = r;
2813 goto exit_inplace_result_object;
2814 }
2815 }
2816 }
2817
2818 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
2819 }
2820
2821exit_inplace_result_object:
2822 if (unlikely(obj_result == NULL)) {
2823 return false;
2824 }
2825
2826 // We got an object handed, that we have to release.
2827 Py_DECREF(*operand1);
2828
2829 // That's our return value then. As we use a dedicated variable, it's
2830 // OK that way.
2831 *operand1 = obj_result;
2832
2833 return true;
2834
2835exit_inplace_exception:
2836 return false;
2837}
2838
2839bool INPLACE_OPERATION_MULT_LIST_INT(PyObject **operand1, PyObject *operand2) {
2840 return _INPLACE_OPERATION_MULT_LIST_INT(operand1, operand2);
2841}
2842#endif
2843
2844#if PYTHON_VERSION < 0x300
2845/* Code referring to "INT" corresponds to Python2 'int' and "LIST" to Python 'list'. */
2846static inline bool _INPLACE_OPERATION_MULT_INT_LIST(PyObject **operand1, PyObject *operand2) {
2847 assert(operand1); // Pointer must be non-null.
2848
2849 CHECK_OBJECT(*operand1);
2850 assert(PyInt_CheckExact(*operand1));
2851 CHECK_OBJECT(operand2);
2852 assert(PyList_CheckExact(operand2));
2853
2854#if defined(_MSC_VER)
2855#pragma warning(push)
2856#pragma warning(disable : 4101)
2857#endif
2858 NUITKA_MAY_BE_UNUSED bool cbool_result;
2859 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2860#if defined(_MSC_VER)
2861#pragma warning(pop)
2862#endif
2863
2864 // No inplace number slot nb_inplace_multiply available for this type.
2865
2866 {
2867 // Slot1 ignored on purpose, type2 takes precedence.
2868
2869 // Statically recognized that coercion is not possible with these types
2870
2871 {
2872 // No sequence repeat slot sq_repeat available for this type.
2873 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
2874 }
2875 if (true) {
2876 if (unlikely(!1)) {
2877 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
2878
2879 goto exit_inplace_exception;
2880 }
2881
2882 {
2883 PyObject *index_value = *operand1;
2884
2885 {
2886 Py_ssize_t count = PyInt_AS_LONG(index_value);
2887 {
2888 ssizeargfunc repeatfunc = PyList_Type.tp_as_sequence->sq_inplace_repeat;
2889 if (repeatfunc == NULL) {
2890 repeatfunc = PyList_Type.tp_as_sequence->sq_repeat;
2891 }
2892 PyObject *r = (*repeatfunc)(operand2, count);
2893
2894 obj_result = r;
2895 goto exit_inplace_result_object;
2896 }
2897 }
2898 }
2899 }
2900
2901 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'list'");
2902 goto exit_inplace_exception;
2903 }
2904
2905exit_inplace_result_object:
2906 if (unlikely(obj_result == NULL)) {
2907 return false;
2908 }
2909
2910 // We got an object handed, that we have to release.
2911 Py_DECREF(*operand1);
2912
2913 // That's our return value then. As we use a dedicated variable, it's
2914 // OK that way.
2915 *operand1 = obj_result;
2916
2917 return true;
2918
2919exit_inplace_exception:
2920 return false;
2921}
2922
2923bool INPLACE_OPERATION_MULT_INT_LIST(PyObject **operand1, PyObject *operand2) {
2924 return _INPLACE_OPERATION_MULT_INT_LIST(operand1, operand2);
2925}
2926#endif
2927
2928/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "LONG" to Python2 'long', Python3
2929 * 'int'. */
2930static inline bool _INPLACE_OPERATION_MULT_UNICODE_LONG(PyObject **operand1, PyObject *operand2) {
2931 assert(operand1); // Pointer must be non-null.
2932
2933 CHECK_OBJECT(*operand1);
2934 assert(PyUnicode_CheckExact(*operand1));
2935 CHECK_OBJECT(operand2);
2936 assert(PyLong_CheckExact(operand2));
2937
2938#if defined(_MSC_VER)
2939#pragma warning(push)
2940#pragma warning(disable : 4101)
2941#endif
2942 NUITKA_MAY_BE_UNUSED bool cbool_result;
2943 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
2944#if defined(_MSC_VER)
2945#pragma warning(pop)
2946#endif
2947
2948 // No inplace number slot nb_inplace_multiply available for this type.
2949
2950 {
2951 // Slot2 ignored on purpose, type1 takes precedence.
2952
2953 // Statically recognized that coercion is not possible with these types
2954
2955 if (unlikely(!1)) {
2956 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
2957
2958 goto exit_inplace_exception;
2959 }
2960
2961 {
2962 PyObject *index_value = operand2;
2963
2964 {
2965 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
2966
2967 /* Above conversion indicates an error as -1 */
2968 if (unlikely(count == -1)) {
2969#if PYTHON_VERSION < 0x300
2970 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
2971#else
2972 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
2973#endif
2974 goto exit_inplace_exception;
2975 }
2976 {
2977 ssizeargfunc repeatfunc = NULL;
2978 if (repeatfunc == NULL) {
2979 repeatfunc = PyUnicode_Type.tp_as_sequence->sq_repeat;
2980 }
2981 PyObject *r = (*repeatfunc)(*operand1, count);
2982
2983 obj_result = r;
2984 goto exit_inplace_result_object;
2985 }
2986 }
2987 }
2988
2989 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
2990 }
2991
2992exit_inplace_result_object:
2993 if (unlikely(obj_result == NULL)) {
2994 return false;
2995 }
2996
2997 // We got an object handed, that we have to release.
2998 Py_DECREF(*operand1);
2999
3000 // That's our return value then. As we use a dedicated variable, it's
3001 // OK that way.
3002 *operand1 = obj_result;
3003
3004 return true;
3005
3006exit_inplace_exception:
3007 return false;
3008}
3009
3010bool INPLACE_OPERATION_MULT_UNICODE_LONG(PyObject **operand1, PyObject *operand2) {
3011 return _INPLACE_OPERATION_MULT_UNICODE_LONG(operand1, operand2);
3012}
3013
3014/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "UNICODE" to Python2 'unicode', Python3
3015 * 'str'. */
3016static inline bool _INPLACE_OPERATION_MULT_LONG_UNICODE(PyObject **operand1, PyObject *operand2) {
3017 assert(operand1); // Pointer must be non-null.
3018
3019 CHECK_OBJECT(*operand1);
3020 assert(PyLong_CheckExact(*operand1));
3021 CHECK_OBJECT(operand2);
3022 assert(PyUnicode_CheckExact(operand2));
3023
3024#if defined(_MSC_VER)
3025#pragma warning(push)
3026#pragma warning(disable : 4101)
3027#endif
3028 NUITKA_MAY_BE_UNUSED bool cbool_result;
3029 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3030#if defined(_MSC_VER)
3031#pragma warning(pop)
3032#endif
3033
3034 // No inplace number slot nb_inplace_multiply available for this type.
3035
3036 {
3037 // Slot1 ignored on purpose, type2 takes precedence.
3038
3039 // Statically recognized that coercion is not possible with these types
3040
3041 {
3042 // No sequence repeat slot sq_repeat available for this type.
3043 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
3044 }
3045 if (true) {
3046 if (unlikely(!1)) {
3047 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
3048
3049 goto exit_inplace_exception;
3050 }
3051
3052 {
3053 PyObject *index_value = *operand1;
3054
3055 {
3056 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3057
3058 /* Above conversion indicates an error as -1 */
3059 if (unlikely(count == -1)) {
3060#if PYTHON_VERSION < 0x300
3061 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
3062#else
3063 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3064#endif
3065 goto exit_inplace_exception;
3066 }
3067 {
3068 ssizeargfunc repeatfunc = NULL;
3069 if (repeatfunc == NULL) {
3070 repeatfunc = PyUnicode_Type.tp_as_sequence->sq_repeat;
3071 }
3072 PyObject *r = (*repeatfunc)(operand2, count);
3073
3074 obj_result = r;
3075 goto exit_inplace_result_object;
3076 }
3077 }
3078 }
3079 }
3080
3081#if PYTHON_VERSION < 0x300
3082 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and 'unicode'");
3083#else
3084 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'str'");
3085#endif
3086 goto exit_inplace_exception;
3087 }
3088
3089exit_inplace_result_object:
3090 if (unlikely(obj_result == NULL)) {
3091 return false;
3092 }
3093
3094 // We got an object handed, that we have to release.
3095 Py_DECREF(*operand1);
3096
3097 // That's our return value then. As we use a dedicated variable, it's
3098 // OK that way.
3099 *operand1 = obj_result;
3100
3101 return true;
3102
3103exit_inplace_exception:
3104 return false;
3105}
3106
3107bool INPLACE_OPERATION_MULT_LONG_UNICODE(PyObject **operand1, PyObject *operand2) {
3108 return _INPLACE_OPERATION_MULT_LONG_UNICODE(operand1, operand2);
3109}
3110
3111#if PYTHON_VERSION >= 0x300
3112/* Code referring to "BYTES" corresponds to Python3 'bytes' and "LONG" to Python2 'long', Python3 'int'. */
3113static inline bool _INPLACE_OPERATION_MULT_BYTES_LONG(PyObject **operand1, PyObject *operand2) {
3114 assert(operand1); // Pointer must be non-null.
3115
3116 CHECK_OBJECT(*operand1);
3117 assert(PyBytes_CheckExact(*operand1));
3118 CHECK_OBJECT(operand2);
3119 assert(PyLong_CheckExact(operand2));
3120
3121#if defined(_MSC_VER)
3122#pragma warning(push)
3123#pragma warning(disable : 4101)
3124#endif
3125 NUITKA_MAY_BE_UNUSED bool cbool_result;
3126 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3127#if defined(_MSC_VER)
3128#pragma warning(pop)
3129#endif
3130
3131 // No inplace number slot nb_inplace_multiply available for this type.
3132
3133 {
3134 // Slot2 ignored on purpose, type1 takes precedence.
3135
3136 // Statically recognized that coercion is not possible with these types
3137
3138 if (unlikely(!1)) {
3139 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
3140
3141 goto exit_inplace_exception;
3142 }
3143
3144 {
3145 PyObject *index_value = operand2;
3146
3147 {
3148 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3149
3150 /* Above conversion indicates an error as -1 */
3151 if (unlikely(count == -1)) {
3152 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3153 goto exit_inplace_exception;
3154 }
3155 {
3156 ssizeargfunc repeatfunc = NULL;
3157 if (repeatfunc == NULL) {
3158 repeatfunc = PyBytes_Type.tp_as_sequence->sq_repeat;
3159 }
3160 PyObject *r = (*repeatfunc)(*operand1, count);
3161
3162 obj_result = r;
3163 goto exit_inplace_result_object;
3164 }
3165 }
3166 }
3167
3168 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
3169 }
3170
3171exit_inplace_result_object:
3172 if (unlikely(obj_result == NULL)) {
3173 return false;
3174 }
3175
3176 // We got an object handed, that we have to release.
3177 Py_DECREF(*operand1);
3178
3179 // That's our return value then. As we use a dedicated variable, it's
3180 // OK that way.
3181 *operand1 = obj_result;
3182
3183 return true;
3184
3185exit_inplace_exception:
3186 return false;
3187}
3188
3189bool INPLACE_OPERATION_MULT_BYTES_LONG(PyObject **operand1, PyObject *operand2) {
3190 return _INPLACE_OPERATION_MULT_BYTES_LONG(operand1, operand2);
3191}
3192#endif
3193
3194#if PYTHON_VERSION >= 0x300
3195/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "BYTES" to Python3 'bytes'. */
3196static inline bool _INPLACE_OPERATION_MULT_LONG_BYTES(PyObject **operand1, PyObject *operand2) {
3197 assert(operand1); // Pointer must be non-null.
3198
3199 CHECK_OBJECT(*operand1);
3200 assert(PyLong_CheckExact(*operand1));
3201 CHECK_OBJECT(operand2);
3202 assert(PyBytes_CheckExact(operand2));
3203
3204#if defined(_MSC_VER)
3205#pragma warning(push)
3206#pragma warning(disable : 4101)
3207#endif
3208 NUITKA_MAY_BE_UNUSED bool cbool_result;
3209 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3210#if defined(_MSC_VER)
3211#pragma warning(pop)
3212#endif
3213
3214 // No inplace number slot nb_inplace_multiply available for this type.
3215
3216 {
3217 // Slot1 ignored on purpose, type2 takes precedence.
3218
3219 // Statically recognized that coercion is not possible with these types
3220
3221 {
3222 // No sequence repeat slot sq_repeat available for this type.
3223 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
3224 }
3225 if (true) {
3226 if (unlikely(!1)) {
3227 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
3228
3229 goto exit_inplace_exception;
3230 }
3231
3232 {
3233 PyObject *index_value = *operand1;
3234
3235 {
3236 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3237
3238 /* Above conversion indicates an error as -1 */
3239 if (unlikely(count == -1)) {
3240 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3241 goto exit_inplace_exception;
3242 }
3243 {
3244 ssizeargfunc repeatfunc = NULL;
3245 if (repeatfunc == NULL) {
3246 repeatfunc = PyBytes_Type.tp_as_sequence->sq_repeat;
3247 }
3248 PyObject *r = (*repeatfunc)(operand2, count);
3249
3250 obj_result = r;
3251 goto exit_inplace_result_object;
3252 }
3253 }
3254 }
3255 }
3256
3257 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'bytes'");
3258 goto exit_inplace_exception;
3259 }
3260
3261exit_inplace_result_object:
3262 if (unlikely(obj_result == NULL)) {
3263 return false;
3264 }
3265
3266 // We got an object handed, that we have to release.
3267 Py_DECREF(*operand1);
3268
3269 // That's our return value then. As we use a dedicated variable, it's
3270 // OK that way.
3271 *operand1 = obj_result;
3272
3273 return true;
3274
3275exit_inplace_exception:
3276 return false;
3277}
3278
3279bool INPLACE_OPERATION_MULT_LONG_BYTES(PyObject **operand1, PyObject *operand2) {
3280 return _INPLACE_OPERATION_MULT_LONG_BYTES(operand1, operand2);
3281}
3282#endif
3283
3284/* Code referring to "TUPLE" corresponds to Python 'tuple' and "LONG" to Python2 'long', Python3 'int'. */
3285static inline bool _INPLACE_OPERATION_MULT_TUPLE_LONG(PyObject **operand1, PyObject *operand2) {
3286 assert(operand1); // Pointer must be non-null.
3287
3288 CHECK_OBJECT(*operand1);
3289 assert(PyTuple_CheckExact(*operand1));
3290 CHECK_OBJECT(operand2);
3291 assert(PyLong_CheckExact(operand2));
3292
3293#if defined(_MSC_VER)
3294#pragma warning(push)
3295#pragma warning(disable : 4101)
3296#endif
3297 NUITKA_MAY_BE_UNUSED bool cbool_result;
3298 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3299#if defined(_MSC_VER)
3300#pragma warning(pop)
3301#endif
3302
3303 // No inplace number slot nb_inplace_multiply available for this type.
3304
3305 {
3306 // Slot2 ignored on purpose, type1 takes precedence.
3307
3308 // Statically recognized that coercion is not possible with these types
3309
3310 if (unlikely(!1)) {
3311 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
3312
3313 goto exit_inplace_exception;
3314 }
3315
3316 {
3317 PyObject *index_value = operand2;
3318
3319 {
3320 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3321
3322 /* Above conversion indicates an error as -1 */
3323 if (unlikely(count == -1)) {
3324#if PYTHON_VERSION < 0x300
3325 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
3326#else
3327 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3328#endif
3329 goto exit_inplace_exception;
3330 }
3331 {
3332 ssizeargfunc repeatfunc = NULL;
3333 if (repeatfunc == NULL) {
3334 repeatfunc = PyTuple_Type.tp_as_sequence->sq_repeat;
3335 }
3336 PyObject *r = (*repeatfunc)(*operand1, count);
3337
3338 obj_result = r;
3339 goto exit_inplace_result_object;
3340 }
3341 }
3342 }
3343
3344 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
3345 }
3346
3347exit_inplace_result_object:
3348 if (unlikely(obj_result == NULL)) {
3349 return false;
3350 }
3351
3352 // We got an object handed, that we have to release.
3353 Py_DECREF(*operand1);
3354
3355 // That's our return value then. As we use a dedicated variable, it's
3356 // OK that way.
3357 *operand1 = obj_result;
3358
3359 return true;
3360
3361exit_inplace_exception:
3362 return false;
3363}
3364
3365bool INPLACE_OPERATION_MULT_TUPLE_LONG(PyObject **operand1, PyObject *operand2) {
3366 return _INPLACE_OPERATION_MULT_TUPLE_LONG(operand1, operand2);
3367}
3368
3369/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "TUPLE" to Python 'tuple'. */
3370static inline bool _INPLACE_OPERATION_MULT_LONG_TUPLE(PyObject **operand1, PyObject *operand2) {
3371 assert(operand1); // Pointer must be non-null.
3372
3373 CHECK_OBJECT(*operand1);
3374 assert(PyLong_CheckExact(*operand1));
3375 CHECK_OBJECT(operand2);
3376 assert(PyTuple_CheckExact(operand2));
3377
3378#if defined(_MSC_VER)
3379#pragma warning(push)
3380#pragma warning(disable : 4101)
3381#endif
3382 NUITKA_MAY_BE_UNUSED bool cbool_result;
3383 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3384#if defined(_MSC_VER)
3385#pragma warning(pop)
3386#endif
3387
3388 // No inplace number slot nb_inplace_multiply available for this type.
3389
3390 {
3391 // Slot1 ignored on purpose, type2 takes precedence.
3392
3393 // Statically recognized that coercion is not possible with these types
3394
3395 {
3396 // No sequence repeat slot sq_repeat available for this type.
3397 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
3398 }
3399 if (true) {
3400 if (unlikely(!1)) {
3401 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
3402
3403 goto exit_inplace_exception;
3404 }
3405
3406 {
3407 PyObject *index_value = *operand1;
3408
3409 {
3410 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3411
3412 /* Above conversion indicates an error as -1 */
3413 if (unlikely(count == -1)) {
3414#if PYTHON_VERSION < 0x300
3415 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
3416#else
3417 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3418#endif
3419 goto exit_inplace_exception;
3420 }
3421 {
3422 ssizeargfunc repeatfunc = NULL;
3423 if (repeatfunc == NULL) {
3424 repeatfunc = PyTuple_Type.tp_as_sequence->sq_repeat;
3425 }
3426 PyObject *r = (*repeatfunc)(operand2, count);
3427
3428 obj_result = r;
3429 goto exit_inplace_result_object;
3430 }
3431 }
3432 }
3433 }
3434
3435#if PYTHON_VERSION < 0x300
3436 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and 'tuple'");
3437#else
3438 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'tuple'");
3439#endif
3440 goto exit_inplace_exception;
3441 }
3442
3443exit_inplace_result_object:
3444 if (unlikely(obj_result == NULL)) {
3445 return false;
3446 }
3447
3448 // We got an object handed, that we have to release.
3449 Py_DECREF(*operand1);
3450
3451 // That's our return value then. As we use a dedicated variable, it's
3452 // OK that way.
3453 *operand1 = obj_result;
3454
3455 return true;
3456
3457exit_inplace_exception:
3458 return false;
3459}
3460
3461bool INPLACE_OPERATION_MULT_LONG_TUPLE(PyObject **operand1, PyObject *operand2) {
3462 return _INPLACE_OPERATION_MULT_LONG_TUPLE(operand1, operand2);
3463}
3464
3465/* Code referring to "LIST" corresponds to Python 'list' and "LONG" to Python2 'long', Python3 'int'. */
3466static inline bool _INPLACE_OPERATION_MULT_LIST_LONG(PyObject **operand1, PyObject *operand2) {
3467 assert(operand1); // Pointer must be non-null.
3468
3469 CHECK_OBJECT(*operand1);
3470 assert(PyList_CheckExact(*operand1));
3471 CHECK_OBJECT(operand2);
3472 assert(PyLong_CheckExact(operand2));
3473
3474#if defined(_MSC_VER)
3475#pragma warning(push)
3476#pragma warning(disable : 4101)
3477#endif
3478 NUITKA_MAY_BE_UNUSED bool cbool_result;
3479 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3480#if defined(_MSC_VER)
3481#pragma warning(pop)
3482#endif
3483
3484 // No inplace number slot nb_inplace_multiply available for this type.
3485
3486 {
3487 // Slot2 ignored on purpose, type1 takes precedence.
3488
3489 // Statically recognized that coercion is not possible with these types
3490
3491 if (unlikely(!1)) {
3492 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
3493
3494 goto exit_inplace_exception;
3495 }
3496
3497 {
3498 PyObject *index_value = operand2;
3499
3500 {
3501 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3502
3503 /* Above conversion indicates an error as -1 */
3504 if (unlikely(count == -1)) {
3505#if PYTHON_VERSION < 0x300
3506 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
3507#else
3508 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3509#endif
3510 goto exit_inplace_exception;
3511 }
3512 {
3513 ssizeargfunc repeatfunc = PyList_Type.tp_as_sequence->sq_inplace_repeat;
3514 if (repeatfunc == NULL) {
3515 repeatfunc = PyList_Type.tp_as_sequence->sq_repeat;
3516 }
3517 PyObject *r = (*repeatfunc)(*operand1, count);
3518
3519 obj_result = r;
3520 goto exit_inplace_result_object;
3521 }
3522 }
3523 }
3524
3525 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
3526 }
3527
3528exit_inplace_result_object:
3529 if (unlikely(obj_result == NULL)) {
3530 return false;
3531 }
3532
3533 // We got an object handed, that we have to release.
3534 Py_DECREF(*operand1);
3535
3536 // That's our return value then. As we use a dedicated variable, it's
3537 // OK that way.
3538 *operand1 = obj_result;
3539
3540 return true;
3541
3542exit_inplace_exception:
3543 return false;
3544}
3545
3546bool INPLACE_OPERATION_MULT_LIST_LONG(PyObject **operand1, PyObject *operand2) {
3547 return _INPLACE_OPERATION_MULT_LIST_LONG(operand1, operand2);
3548}
3549
3550/* Code referring to "LONG" corresponds to Python2 'long', Python3 'int' and "LIST" to Python 'list'. */
3551static inline bool _INPLACE_OPERATION_MULT_LONG_LIST(PyObject **operand1, PyObject *operand2) {
3552 assert(operand1); // Pointer must be non-null.
3553
3554 CHECK_OBJECT(*operand1);
3555 assert(PyLong_CheckExact(*operand1));
3556 CHECK_OBJECT(operand2);
3557 assert(PyList_CheckExact(operand2));
3558
3559#if defined(_MSC_VER)
3560#pragma warning(push)
3561#pragma warning(disable : 4101)
3562#endif
3563 NUITKA_MAY_BE_UNUSED bool cbool_result;
3564 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3565#if defined(_MSC_VER)
3566#pragma warning(pop)
3567#endif
3568
3569 // No inplace number slot nb_inplace_multiply available for this type.
3570
3571 {
3572 // Slot1 ignored on purpose, type2 takes precedence.
3573
3574 // Statically recognized that coercion is not possible with these types
3575
3576 {
3577 // No sequence repeat slot sq_repeat available for this type.
3578 // No inplace sequence repeat slot sq_inplace_repeat available for this type.
3579 }
3580 if (true) {
3581 if (unlikely(!1)) {
3582 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", *operand1);
3583
3584 goto exit_inplace_exception;
3585 }
3586
3587 {
3588 PyObject *index_value = *operand1;
3589
3590 {
3591 Py_ssize_t count = CONVERT_LONG_TO_REPEAT_FACTOR(index_value);
3592
3593 /* Above conversion indicates an error as -1 */
3594 if (unlikely(count == -1)) {
3595#if PYTHON_VERSION < 0x300
3596 PyErr_Format(PyExc_OverflowError, "cannot fit 'long' into an index-sized integer");
3597#else
3598 PyErr_Format(PyExc_OverflowError, "cannot fit 'int' into an index-sized integer");
3599#endif
3600 goto exit_inplace_exception;
3601 }
3602 {
3603 ssizeargfunc repeatfunc = PyList_Type.tp_as_sequence->sq_inplace_repeat;
3604 if (repeatfunc == NULL) {
3605 repeatfunc = PyList_Type.tp_as_sequence->sq_repeat;
3606 }
3607 PyObject *r = (*repeatfunc)(operand2, count);
3608
3609 obj_result = r;
3610 goto exit_inplace_result_object;
3611 }
3612 }
3613 }
3614 }
3615
3616#if PYTHON_VERSION < 0x300
3617 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'long' and 'list'");
3618#else
3619 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: 'int' and 'list'");
3620#endif
3621 goto exit_inplace_exception;
3622 }
3623
3624exit_inplace_result_object:
3625 if (unlikely(obj_result == NULL)) {
3626 return false;
3627 }
3628
3629 // We got an object handed, that we have to release.
3630 Py_DECREF(*operand1);
3631
3632 // That's our return value then. As we use a dedicated variable, it's
3633 // OK that way.
3634 *operand1 = obj_result;
3635
3636 return true;
3637
3638exit_inplace_exception:
3639 return false;
3640}
3641
3642bool INPLACE_OPERATION_MULT_LONG_LIST(PyObject **operand1, PyObject *operand2) {
3643 return _INPLACE_OPERATION_MULT_LONG_LIST(operand1, operand2);
3644}
3645
3646#if PYTHON_VERSION < 0x300
3647/* Code referring to "STR" corresponds to Python2 'str' and "OBJECT" to any Python object. */
3648static inline bool _INPLACE_OPERATION_MULT_STR_OBJECT(PyObject **operand1, PyObject *operand2) {
3649 assert(operand1); // Pointer must be non-null.
3650
3651 CHECK_OBJECT(*operand1);
3652 assert(PyString_CheckExact(*operand1));
3653 CHECK_OBJECT(operand2);
3654
3655 PyTypeObject *type2 = Py_TYPE(operand2);
3656
3657#if defined(_MSC_VER)
3658#pragma warning(push)
3659#pragma warning(disable : 4101)
3660#endif
3661 NUITKA_MAY_BE_UNUSED bool cbool_result;
3662 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3663#if defined(_MSC_VER)
3664#pragma warning(pop)
3665#endif
3666
3667 // No inplace number slot nb_inplace_multiply available for this type.
3668
3669 {
3670 binaryfunc slot2 = NULL;
3671
3672 if (!(&PyString_Type == type2)) {
3673 // Different types, need to consider second value slot.
3674
3675 slot2 =
3676 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
3677 }
3678
3679 if (slot2 != NULL) {
3680 PyObject *x = slot2(*operand1, operand2);
3681
3682 if (x != Py_NotImplemented) {
3683 obj_result = x;
3684 goto exit_inplace_result_object;
3685 }
3686
3687 Py_DECREF_IMMORTAL(x);
3688 }
3689
3690#if PYTHON_VERSION < 0x300
3691 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
3692 coercion c2 =
3693 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
3694
3695 if (c2 != NULL) {
3696 PyObject *coerced1 = *operand1;
3697 PyObject *coerced2 = operand2;
3698
3699 int err = c2(&coerced2, &coerced1);
3700
3701 if (unlikely(err < 0)) {
3702 goto exit_inplace_exception;
3703 }
3704
3705 if (err == 0) {
3706 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
3707
3708 if (likely(mv == NULL)) {
3709 binaryfunc slot = mv->nb_multiply;
3710
3711 if (likely(slot != NULL)) {
3712 PyObject *x = slot(coerced1, coerced2);
3713
3714 Py_DECREF(coerced1);
3715 Py_DECREF(coerced2);
3716
3717 obj_result = x;
3718 goto exit_inplace_result_object;
3719 }
3720 }
3721
3722 // nb_coerce took a reference.
3723 Py_DECREF(coerced1);
3724 Py_DECREF(coerced2);
3725 }
3726 }
3727 }
3728#endif
3729
3730 if (unlikely(!Nuitka_Index_Check(operand2))) {
3731 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
3732
3733 goto exit_inplace_exception;
3734 }
3735
3736 {
3737 PyObject *index_value = Nuitka_Number_Index(operand2);
3738
3739 if (unlikely(index_value == NULL)) {
3740 goto exit_inplace_exception;
3741 }
3742
3743 {
3744 Py_ssize_t count = CONVERT_TO_REPEAT_FACTOR(index_value);
3745
3746 Py_DECREF(index_value);
3747
3748 /* Above conversion indicates an error as -1 */
3749 if (unlikely(count == -1)) {
3750 PyErr_Format(PyExc_OverflowError, "cannot fit '%s' into an index-sized integer", type2->tp_name);
3751 goto exit_inplace_exception;
3752 }
3753 {
3754 ssizeargfunc repeatfunc = NULL;
3755 if (repeatfunc == NULL) {
3756 repeatfunc = PyString_Type.tp_as_sequence->sq_repeat;
3757 }
3758 PyObject *r = (*repeatfunc)(*operand1, count);
3759
3760 obj_result = r;
3761 goto exit_inplace_result_object;
3762 }
3763 }
3764 }
3765
3766 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
3767 }
3768
3769exit_inplace_result_object:
3770 if (unlikely(obj_result == NULL)) {
3771 return false;
3772 }
3773
3774 // We got an object handed, that we have to release.
3775 Py_DECREF(*operand1);
3776
3777 // That's our return value then. As we use a dedicated variable, it's
3778 // OK that way.
3779 *operand1 = obj_result;
3780
3781 return true;
3782
3783exit_inplace_exception:
3784 return false;
3785}
3786
3787bool INPLACE_OPERATION_MULT_STR_OBJECT(PyObject **operand1, PyObject *operand2) {
3788 return _INPLACE_OPERATION_MULT_STR_OBJECT(operand1, operand2);
3789}
3790#endif
3791
3792/* Code referring to "UNICODE" corresponds to Python2 'unicode', Python3 'str' and "OBJECT" to any Python object. */
3793static inline bool _INPLACE_OPERATION_MULT_UNICODE_OBJECT(PyObject **operand1, PyObject *operand2) {
3794 assert(operand1); // Pointer must be non-null.
3795
3796 CHECK_OBJECT(*operand1);
3797 assert(PyUnicode_CheckExact(*operand1));
3798 CHECK_OBJECT(operand2);
3799
3800 PyTypeObject *type2 = Py_TYPE(operand2);
3801
3802#if defined(_MSC_VER)
3803#pragma warning(push)
3804#pragma warning(disable : 4101)
3805#endif
3806 NUITKA_MAY_BE_UNUSED bool cbool_result;
3807 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3808#if defined(_MSC_VER)
3809#pragma warning(pop)
3810#endif
3811
3812 // No inplace number slot nb_inplace_multiply available for this type.
3813
3814 {
3815 binaryfunc slot2 = NULL;
3816
3817 if (!(&PyUnicode_Type == type2)) {
3818 // Different types, need to consider second value slot.
3819
3820 slot2 =
3821 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
3822 }
3823
3824 if (slot2 != NULL) {
3825 PyObject *x = slot2(*operand1, operand2);
3826
3827 if (x != Py_NotImplemented) {
3828 obj_result = x;
3829 goto exit_inplace_result_object;
3830 }
3831
3832 Py_DECREF_IMMORTAL(x);
3833 }
3834
3835#if PYTHON_VERSION < 0x300
3836 if (!1 || !NEW_STYLE_NUMBER_TYPE(type2)) {
3837 coercion c2 =
3838 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
3839
3840 if (c2 != NULL) {
3841 PyObject *coerced1 = *operand1;
3842 PyObject *coerced2 = operand2;
3843
3844 int err = c2(&coerced2, &coerced1);
3845
3846 if (unlikely(err < 0)) {
3847 goto exit_inplace_exception;
3848 }
3849
3850 if (err == 0) {
3851 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
3852
3853 if (likely(mv == NULL)) {
3854 binaryfunc slot = mv->nb_multiply;
3855
3856 if (likely(slot != NULL)) {
3857 PyObject *x = slot(coerced1, coerced2);
3858
3859 Py_DECREF(coerced1);
3860 Py_DECREF(coerced2);
3861
3862 obj_result = x;
3863 goto exit_inplace_result_object;
3864 }
3865 }
3866
3867 // nb_coerce took a reference.
3868 Py_DECREF(coerced1);
3869 Py_DECREF(coerced2);
3870 }
3871 }
3872 }
3873#endif
3874
3875 if (unlikely(!Nuitka_Index_Check(operand2))) {
3876 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
3877
3878 goto exit_inplace_exception;
3879 }
3880
3881 {
3882 PyObject *index_value = Nuitka_Number_Index(operand2);
3883
3884 if (unlikely(index_value == NULL)) {
3885 goto exit_inplace_exception;
3886 }
3887
3888 {
3889 Py_ssize_t count = CONVERT_TO_REPEAT_FACTOR(index_value);
3890
3891 Py_DECREF(index_value);
3892
3893 /* Above conversion indicates an error as -1 */
3894 if (unlikely(count == -1)) {
3895 PyErr_Format(PyExc_OverflowError, "cannot fit '%s' into an index-sized integer", type2->tp_name);
3896 goto exit_inplace_exception;
3897 }
3898 {
3899 ssizeargfunc repeatfunc = NULL;
3900 if (repeatfunc == NULL) {
3901 repeatfunc = PyUnicode_Type.tp_as_sequence->sq_repeat;
3902 }
3903 PyObject *r = (*repeatfunc)(*operand1, count);
3904
3905 obj_result = r;
3906 goto exit_inplace_result_object;
3907 }
3908 }
3909 }
3910
3911 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
3912 }
3913
3914exit_inplace_result_object:
3915 if (unlikely(obj_result == NULL)) {
3916 return false;
3917 }
3918
3919 // We got an object handed, that we have to release.
3920 Py_DECREF(*operand1);
3921
3922 // That's our return value then. As we use a dedicated variable, it's
3923 // OK that way.
3924 *operand1 = obj_result;
3925
3926 return true;
3927
3928exit_inplace_exception:
3929 return false;
3930}
3931
3932bool INPLACE_OPERATION_MULT_UNICODE_OBJECT(PyObject **operand1, PyObject *operand2) {
3933 return _INPLACE_OPERATION_MULT_UNICODE_OBJECT(operand1, operand2);
3934}
3935
3936#if PYTHON_VERSION >= 0x300
3937/* Code referring to "BYTES" corresponds to Python3 'bytes' and "OBJECT" to any Python object. */
3938static inline bool _INPLACE_OPERATION_MULT_BYTES_OBJECT(PyObject **operand1, PyObject *operand2) {
3939 assert(operand1); // Pointer must be non-null.
3940
3941 CHECK_OBJECT(*operand1);
3942 assert(PyBytes_CheckExact(*operand1));
3943 CHECK_OBJECT(operand2);
3944
3945 PyTypeObject *type2 = Py_TYPE(operand2);
3946
3947#if defined(_MSC_VER)
3948#pragma warning(push)
3949#pragma warning(disable : 4101)
3950#endif
3951 NUITKA_MAY_BE_UNUSED bool cbool_result;
3952 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
3953#if defined(_MSC_VER)
3954#pragma warning(pop)
3955#endif
3956
3957 // No inplace number slot nb_inplace_multiply available for this type.
3958
3959 {
3960 binaryfunc slot2 = NULL;
3961
3962 if (!(&PyBytes_Type == type2)) {
3963 // Different types, need to consider second value slot.
3964
3965 slot2 =
3966 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
3967 }
3968
3969 if (slot2 != NULL) {
3970 PyObject *x = slot2(*operand1, operand2);
3971
3972 if (x != Py_NotImplemented) {
3973 obj_result = x;
3974 goto exit_inplace_result_object;
3975 }
3976
3977 Py_DECREF_IMMORTAL(x);
3978 }
3979
3980#if PYTHON_VERSION < 0x300
3981 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
3982 coercion c2 =
3983 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
3984
3985 if (c2 != NULL) {
3986 PyObject *coerced1 = *operand1;
3987 PyObject *coerced2 = operand2;
3988
3989 int err = c2(&coerced2, &coerced1);
3990
3991 if (unlikely(err < 0)) {
3992 goto exit_inplace_exception;
3993 }
3994
3995 if (err == 0) {
3996 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
3997
3998 if (likely(mv == NULL)) {
3999 binaryfunc slot = mv->nb_multiply;
4000
4001 if (likely(slot != NULL)) {
4002 PyObject *x = slot(coerced1, coerced2);
4003
4004 Py_DECREF(coerced1);
4005 Py_DECREF(coerced2);
4006
4007 obj_result = x;
4008 goto exit_inplace_result_object;
4009 }
4010 }
4011
4012 // nb_coerce took a reference.
4013 Py_DECREF(coerced1);
4014 Py_DECREF(coerced2);
4015 }
4016 }
4017 }
4018#endif
4019
4020 if (unlikely(!Nuitka_Index_Check(operand2))) {
4021 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
4022
4023 goto exit_inplace_exception;
4024 }
4025
4026 {
4027 PyObject *index_value = Nuitka_Number_Index(operand2);
4028
4029 if (unlikely(index_value == NULL)) {
4030 goto exit_inplace_exception;
4031 }
4032
4033 {
4034 Py_ssize_t count = CONVERT_TO_REPEAT_FACTOR(index_value);
4035
4036 Py_DECREF(index_value);
4037
4038 /* Above conversion indicates an error as -1 */
4039 if (unlikely(count == -1)) {
4040 PyErr_Format(PyExc_OverflowError, "cannot fit '%s' into an index-sized integer", type2->tp_name);
4041 goto exit_inplace_exception;
4042 }
4043 {
4044 ssizeargfunc repeatfunc = NULL;
4045 if (repeatfunc == NULL) {
4046 repeatfunc = PyBytes_Type.tp_as_sequence->sq_repeat;
4047 }
4048 PyObject *r = (*repeatfunc)(*operand1, count);
4049
4050 obj_result = r;
4051 goto exit_inplace_result_object;
4052 }
4053 }
4054 }
4055
4056 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4057 }
4058
4059exit_inplace_result_object:
4060 if (unlikely(obj_result == NULL)) {
4061 return false;
4062 }
4063
4064 // We got an object handed, that we have to release.
4065 Py_DECREF(*operand1);
4066
4067 // That's our return value then. As we use a dedicated variable, it's
4068 // OK that way.
4069 *operand1 = obj_result;
4070
4071 return true;
4072
4073exit_inplace_exception:
4074 return false;
4075}
4076
4077bool INPLACE_OPERATION_MULT_BYTES_OBJECT(PyObject **operand1, PyObject *operand2) {
4078 return _INPLACE_OPERATION_MULT_BYTES_OBJECT(operand1, operand2);
4079}
4080#endif
4081
4082/* Code referring to "TUPLE" corresponds to Python 'tuple' and "OBJECT" to any Python object. */
4083static inline bool _INPLACE_OPERATION_MULT_TUPLE_OBJECT(PyObject **operand1, PyObject *operand2) {
4084 assert(operand1); // Pointer must be non-null.
4085
4086 CHECK_OBJECT(*operand1);
4087 assert(PyTuple_CheckExact(*operand1));
4088 CHECK_OBJECT(operand2);
4089
4090 PyTypeObject *type2 = Py_TYPE(operand2);
4091
4092#if defined(_MSC_VER)
4093#pragma warning(push)
4094#pragma warning(disable : 4101)
4095#endif
4096 NUITKA_MAY_BE_UNUSED bool cbool_result;
4097 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4098#if defined(_MSC_VER)
4099#pragma warning(pop)
4100#endif
4101
4102 // No inplace number slot nb_inplace_multiply available for this type.
4103
4104 {
4105 binaryfunc slot2 = NULL;
4106
4107 if (!(&PyTuple_Type == type2)) {
4108 // Different types, need to consider second value slot.
4109
4110 slot2 =
4111 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
4112 }
4113
4114 if (slot2 != NULL) {
4115 PyObject *x = slot2(*operand1, operand2);
4116
4117 if (x != Py_NotImplemented) {
4118 obj_result = x;
4119 goto exit_inplace_result_object;
4120 }
4121
4122 Py_DECREF_IMMORTAL(x);
4123 }
4124
4125#if PYTHON_VERSION < 0x300
4126 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
4127 coercion c2 =
4128 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4129
4130 if (c2 != NULL) {
4131 PyObject *coerced1 = *operand1;
4132 PyObject *coerced2 = operand2;
4133
4134 int err = c2(&coerced2, &coerced1);
4135
4136 if (unlikely(err < 0)) {
4137 goto exit_inplace_exception;
4138 }
4139
4140 if (err == 0) {
4141 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4142
4143 if (likely(mv == NULL)) {
4144 binaryfunc slot = mv->nb_multiply;
4145
4146 if (likely(slot != NULL)) {
4147 PyObject *x = slot(coerced1, coerced2);
4148
4149 Py_DECREF(coerced1);
4150 Py_DECREF(coerced2);
4151
4152 obj_result = x;
4153 goto exit_inplace_result_object;
4154 }
4155 }
4156
4157 // nb_coerce took a reference.
4158 Py_DECREF(coerced1);
4159 Py_DECREF(coerced2);
4160 }
4161 }
4162 }
4163#endif
4164
4165 if (unlikely(!Nuitka_Index_Check(operand2))) {
4166 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
4167
4168 goto exit_inplace_exception;
4169 }
4170
4171 {
4172 PyObject *index_value = Nuitka_Number_Index(operand2);
4173
4174 if (unlikely(index_value == NULL)) {
4175 goto exit_inplace_exception;
4176 }
4177
4178 {
4179 Py_ssize_t count = CONVERT_TO_REPEAT_FACTOR(index_value);
4180
4181 Py_DECREF(index_value);
4182
4183 /* Above conversion indicates an error as -1 */
4184 if (unlikely(count == -1)) {
4185 PyErr_Format(PyExc_OverflowError, "cannot fit '%s' into an index-sized integer", type2->tp_name);
4186 goto exit_inplace_exception;
4187 }
4188 {
4189 ssizeargfunc repeatfunc = NULL;
4190 if (repeatfunc == NULL) {
4191 repeatfunc = PyTuple_Type.tp_as_sequence->sq_repeat;
4192 }
4193 PyObject *r = (*repeatfunc)(*operand1, count);
4194
4195 obj_result = r;
4196 goto exit_inplace_result_object;
4197 }
4198 }
4199 }
4200
4201 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4202 }
4203
4204exit_inplace_result_object:
4205 if (unlikely(obj_result == NULL)) {
4206 return false;
4207 }
4208
4209 // We got an object handed, that we have to release.
4210 Py_DECREF(*operand1);
4211
4212 // That's our return value then. As we use a dedicated variable, it's
4213 // OK that way.
4214 *operand1 = obj_result;
4215
4216 return true;
4217
4218exit_inplace_exception:
4219 return false;
4220}
4221
4222bool INPLACE_OPERATION_MULT_TUPLE_OBJECT(PyObject **operand1, PyObject *operand2) {
4223 return _INPLACE_OPERATION_MULT_TUPLE_OBJECT(operand1, operand2);
4224}
4225
4226/* Code referring to "LIST" corresponds to Python 'list' and "OBJECT" to any Python object. */
4227static inline bool _INPLACE_OPERATION_MULT_LIST_OBJECT(PyObject **operand1, PyObject *operand2) {
4228 assert(operand1); // Pointer must be non-null.
4229
4230 CHECK_OBJECT(*operand1);
4231 assert(PyList_CheckExact(*operand1));
4232 CHECK_OBJECT(operand2);
4233
4234 PyTypeObject *type2 = Py_TYPE(operand2);
4235
4236#if defined(_MSC_VER)
4237#pragma warning(push)
4238#pragma warning(disable : 4101)
4239#endif
4240 NUITKA_MAY_BE_UNUSED bool cbool_result;
4241 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4242#if defined(_MSC_VER)
4243#pragma warning(pop)
4244#endif
4245
4246 // No inplace number slot nb_inplace_multiply available for this type.
4247
4248 {
4249 binaryfunc slot2 = NULL;
4250
4251 if (!(&PyList_Type == type2)) {
4252 // Different types, need to consider second value slot.
4253
4254 slot2 =
4255 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
4256 }
4257
4258 if (slot2 != NULL) {
4259 PyObject *x = slot2(*operand1, operand2);
4260
4261 if (x != Py_NotImplemented) {
4262 obj_result = x;
4263 goto exit_inplace_result_object;
4264 }
4265
4266 Py_DECREF_IMMORTAL(x);
4267 }
4268
4269#if PYTHON_VERSION < 0x300
4270 if (!0 || !NEW_STYLE_NUMBER_TYPE(type2)) {
4271 coercion c2 =
4272 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4273
4274 if (c2 != NULL) {
4275 PyObject *coerced1 = *operand1;
4276 PyObject *coerced2 = operand2;
4277
4278 int err = c2(&coerced2, &coerced1);
4279
4280 if (unlikely(err < 0)) {
4281 goto exit_inplace_exception;
4282 }
4283
4284 if (err == 0) {
4285 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4286
4287 if (likely(mv == NULL)) {
4288 binaryfunc slot = mv->nb_multiply;
4289
4290 if (likely(slot != NULL)) {
4291 PyObject *x = slot(coerced1, coerced2);
4292
4293 Py_DECREF(coerced1);
4294 Py_DECREF(coerced2);
4295
4296 obj_result = x;
4297 goto exit_inplace_result_object;
4298 }
4299 }
4300
4301 // nb_coerce took a reference.
4302 Py_DECREF(coerced1);
4303 Py_DECREF(coerced2);
4304 }
4305 }
4306 }
4307#endif
4308
4309 if (unlikely(!Nuitka_Index_Check(operand2))) {
4310 SET_CURRENT_EXCEPTION_TYPE_COMPLAINT("can't multiply sequence by non-int of type '%s'", operand2);
4311
4312 goto exit_inplace_exception;
4313 }
4314
4315 {
4316 PyObject *index_value = Nuitka_Number_Index(operand2);
4317
4318 if (unlikely(index_value == NULL)) {
4319 goto exit_inplace_exception;
4320 }
4321
4322 {
4323 Py_ssize_t count = CONVERT_TO_REPEAT_FACTOR(index_value);
4324
4325 Py_DECREF(index_value);
4326
4327 /* Above conversion indicates an error as -1 */
4328 if (unlikely(count == -1)) {
4329 PyErr_Format(PyExc_OverflowError, "cannot fit '%s' into an index-sized integer", type2->tp_name);
4330 goto exit_inplace_exception;
4331 }
4332 {
4333 ssizeargfunc repeatfunc = PyList_Type.tp_as_sequence->sq_inplace_repeat;
4334 if (repeatfunc == NULL) {
4335 repeatfunc = PyList_Type.tp_as_sequence->sq_repeat;
4336 }
4337 PyObject *r = (*repeatfunc)(*operand1, count);
4338
4339 obj_result = r;
4340 goto exit_inplace_result_object;
4341 }
4342 }
4343 }
4344
4345 NUITKA_CANNOT_GET_HERE("missing error exit annotation");
4346 }
4347
4348exit_inplace_result_object:
4349 if (unlikely(obj_result == NULL)) {
4350 return false;
4351 }
4352
4353 // We got an object handed, that we have to release.
4354 Py_DECREF(*operand1);
4355
4356 // That's our return value then. As we use a dedicated variable, it's
4357 // OK that way.
4358 *operand1 = obj_result;
4359
4360 return true;
4361
4362exit_inplace_exception:
4363 return false;
4364}
4365
4366bool INPLACE_OPERATION_MULT_LIST_OBJECT(PyObject **operand1, PyObject *operand2) {
4367 return _INPLACE_OPERATION_MULT_LIST_OBJECT(operand1, operand2);
4368}
4369
4370/* Code referring to "OBJECT" corresponds to any Python object and "OBJECT" to any Python object. */
4371static inline bool _INPLACE_OPERATION_MULT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
4372 assert(operand1); // Pointer must be non-null.
4373
4374 CHECK_OBJECT(*operand1);
4375 CHECK_OBJECT(operand2);
4376
4377#if PYTHON_VERSION < 0x300
4378 if (PyInt_CheckExact(*operand1) && PyInt_CheckExact(operand2)) {
4379
4380 // Not every code path will make use of all possible results.
4381#if defined(_MSC_VER)
4382#pragma warning(push)
4383#pragma warning(disable : 4101)
4384#endif
4385 NUITKA_MAY_BE_UNUSED bool cbool_result;
4386 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4387 NUITKA_MAY_BE_UNUSED long clong_result;
4388 NUITKA_MAY_BE_UNUSED double cfloat_result;
4389#if defined(_MSC_VER)
4390#pragma warning(pop)
4391#endif
4392
4393 CHECK_OBJECT(*operand1);
4394 assert(PyInt_CheckExact(*operand1));
4395 CHECK_OBJECT(operand2);
4396 assert(PyInt_CheckExact(operand2));
4397
4398 const long a = PyInt_AS_LONG(*operand1);
4399 const long b = PyInt_AS_LONG(operand2);
4400
4401 const long longprod = (long)((unsigned long)a * b);
4402 const double doubleprod = (double)a * (double)b;
4403 const double doubled_longprod = (double)longprod;
4404
4405 if (likely(doubled_longprod == doubleprod)) {
4406 clong_result = longprod;
4407 goto exit_result_ok_clong;
4408 } else {
4409 const double diff = doubled_longprod - doubleprod;
4410 const double absdiff = diff >= 0.0 ? diff : -diff;
4411 const double absprod = doubleprod >= 0.0 ? doubleprod : -doubleprod;
4412
4413 if (likely(32.0 * absdiff <= absprod)) {
4414 clong_result = longprod;
4415 goto exit_result_ok_clong;
4416 }
4417 }
4418
4419 {
4420 PyObject *operand1_object = *operand1;
4421 PyObject *operand2_object = operand2;
4422
4423 PyObject *r = PyLong_Type.tp_as_number->nb_multiply(operand1_object, operand2_object);
4424 assert(r != Py_NotImplemented);
4425
4426 obj_result = r;
4427 goto exit_result_object;
4428 }
4429
4430 exit_result_ok_clong:
4431
4432 // We got an object handed, that we have to release.
4433 Py_DECREF(*operand1);
4434
4435 // That's our return value then. As we use a dedicated variable, it's
4436 // OK that way.
4437 *operand1 = Nuitka_PyInt_FromLong(clong_result);
4438 goto exit_result_ok;
4439
4440 exit_result_object:
4441 if (unlikely(obj_result == NULL)) {
4442 goto exit_result_exception;
4443 }
4444 // We got an object handed, that we have to release.
4445 Py_DECREF(*operand1);
4446
4447 *operand1 = obj_result;
4448 goto exit_result_ok;
4449
4450 exit_result_ok:
4451 return true;
4452
4453 exit_result_exception:
4454 return false;
4455 }
4456#endif
4457
4458 if (Py_TYPE(*operand1) == Py_TYPE(operand2)) {
4459 if (PyFloat_CheckExact(operand2)) {
4460 return _INPLACE_OPERATION_MULT_FLOAT_FLOAT(operand1, operand2);
4461 }
4462#if PYTHON_VERSION >= 0x300
4463 if (PyLong_CheckExact(operand2)) {
4464 return _INPLACE_OPERATION_MULT_LONG_LONG(operand1, operand2);
4465 }
4466#endif
4467 }
4468
4469 PyTypeObject *type1 = Py_TYPE(*operand1);
4470 PyTypeObject *type2 = Py_TYPE(operand2);
4471
4472#if defined(_MSC_VER)
4473#pragma warning(push)
4474#pragma warning(disable : 4101)
4475#endif
4476 NUITKA_MAY_BE_UNUSED bool cbool_result;
4477 NUITKA_MAY_BE_UNUSED PyObject *obj_result;
4478#if defined(_MSC_VER)
4479#pragma warning(pop)
4480#endif
4481
4482 binaryfunc islot =
4483 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_inplace_multiply : NULL;
4484
4485 if (islot != NULL) {
4486 PyObject *x = islot(*operand1, operand2);
4487
4488 if (x != Py_NotImplemented) {
4489 obj_result = x;
4490 goto exit_inplace_result_object;
4491 }
4492
4493 Py_DECREF_IMMORTAL(x);
4494 }
4495
4496 {
4497 binaryfunc slot1 =
4498 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_multiply : NULL;
4499 binaryfunc slot2 = NULL;
4500
4501 if (!(type1 == type2)) {
4502 // Different types, need to consider second value slot.
4503
4504 slot2 =
4505 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_multiply : NULL;
4506
4507 if (slot1 == slot2) {
4508 slot2 = NULL;
4509 }
4510 }
4511
4512 if (slot1 != NULL) {
4513 if (slot2 != NULL) {
4514 if (Nuitka_Type_IsSubtype(type2, type1)) {
4515 PyObject *x = slot2(*operand1, operand2);
4516
4517 if (x != Py_NotImplemented) {
4518 obj_result = x;
4519 goto exit_inplace_result_object;
4520 }
4521
4522 Py_DECREF_IMMORTAL(x);
4523 slot2 = NULL;
4524 }
4525 }
4526
4527 PyObject *x = slot1(*operand1, operand2);
4528
4529 if (x != Py_NotImplemented) {
4530 obj_result = x;
4531 goto exit_inplace_result_object;
4532 }
4533
4534 Py_DECREF_IMMORTAL(x);
4535 }
4536
4537 if (slot2 != NULL) {
4538 PyObject *x = slot2(*operand1, operand2);
4539
4540 if (x != Py_NotImplemented) {
4541 obj_result = x;
4542 goto exit_inplace_result_object;
4543 }
4544
4545 Py_DECREF_IMMORTAL(x);
4546 }
4547
4548#if PYTHON_VERSION < 0x300
4549 if (!NEW_STYLE_NUMBER_TYPE(type1) || !NEW_STYLE_NUMBER_TYPE(type2)) {
4550 coercion c1 =
4551 (type1->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type1)) ? type1->tp_as_number->nb_coerce : NULL;
4552
4553 if (c1 != NULL) {
4554 PyObject *coerced1 = *operand1;
4555 PyObject *coerced2 = operand2;
4556
4557 int err = c1(&coerced1, &coerced2);
4558
4559 if (unlikely(err < 0)) {
4560 goto exit_inplace_exception;
4561 }
4562
4563 if (err == 0) {
4564 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4565
4566 if (likely(mv == NULL)) {
4567 binaryfunc slot = mv->nb_multiply;
4568
4569 if (likely(slot != NULL)) {
4570 PyObject *x = slot(coerced1, coerced2);
4571
4572 Py_DECREF(coerced1);
4573 Py_DECREF(coerced2);
4574
4575 obj_result = x;
4576 goto exit_inplace_result_object;
4577 }
4578 }
4579
4580 // nb_coerce took a reference.
4581 Py_DECREF(coerced1);
4582 Py_DECREF(coerced2);
4583 }
4584 }
4585 coercion c2 =
4586 (type2->tp_as_number != NULL && NEW_STYLE_NUMBER_TYPE(type2)) ? type2->tp_as_number->nb_coerce : NULL;
4587
4588 if (c2 != NULL) {
4589 PyObject *coerced1 = *operand1;
4590 PyObject *coerced2 = operand2;
4591
4592 int err = c2(&coerced2, &coerced1);
4593
4594 if (unlikely(err < 0)) {
4595 goto exit_inplace_exception;
4596 }
4597
4598 if (err == 0) {
4599 PyNumberMethods *mv = Py_TYPE(coerced1)->tp_as_number;
4600
4601 if (likely(mv == NULL)) {
4602 binaryfunc slot = mv->nb_multiply;
4603
4604 if (likely(slot != NULL)) {
4605 PyObject *x = slot(coerced1, coerced2);
4606
4607 Py_DECREF(coerced1);
4608 Py_DECREF(coerced2);
4609
4610 obj_result = x;
4611 goto exit_inplace_result_object;
4612 }
4613 }
4614
4615 // nb_coerce took a reference.
4616 Py_DECREF(coerced1);
4617 Py_DECREF(coerced2);
4618 }
4619 }
4620 }
4621#endif
4622
4623 {
4624 // Special case for "+" and "*", also works as sequence concat/repeat.
4625 ssizeargfunc sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_inplace_repeat : NULL;
4626 if (sq_slot == NULL) {
4627 sq_slot = type1->tp_as_sequence != NULL ? type1->tp_as_sequence->sq_repeat : NULL;
4628 }
4629
4630 if (sq_slot != NULL) {
4631 PyObject *result = SEQUENCE_REPEAT(sq_slot, *operand1, operand2);
4632
4633 obj_result = result;
4634 goto exit_inplace_result_object;
4635 }
4636 }
4637 // Special case for "*", also work with sequence repeat from right argument.
4638 if (type1->tp_as_sequence == NULL) {
4639 ssizeargfunc sq_slot = type2->tp_as_sequence != NULL ? type2->tp_as_sequence->sq_repeat : NULL;
4640
4641 if (sq_slot != NULL) {
4642 PyObject *result = SEQUENCE_REPEAT(sq_slot, operand2, *operand1);
4643
4644 obj_result = result;
4645 goto exit_inplace_result_object;
4646 }
4647 }
4648
4649 PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for *=: '%s' and '%s'", type1->tp_name,
4650 type2->tp_name);
4651 goto exit_inplace_exception;
4652 }
4653
4654exit_inplace_result_object:
4655 if (unlikely(obj_result == NULL)) {
4656 return false;
4657 }
4658
4659 // We got an object handed, that we have to release.
4660 Py_DECREF(*operand1);
4661
4662 // That's our return value then. As we use a dedicated variable, it's
4663 // OK that way.
4664 *operand1 = obj_result;
4665
4666 return true;
4667
4668exit_inplace_exception:
4669 return false;
4670}
4671
4672bool INPLACE_OPERATION_MULT_OBJECT_OBJECT(PyObject **operand1, PyObject *operand2) {
4673 return _INPLACE_OPERATION_MULT_OBJECT_OBJECT(operand1, operand2);
4674}
4675
4676// Part of "Nuitka", an optimizing Python compiler that is compatible and
4677// integrates with CPython, but also works on its own.
4678//
4679// Licensed under the Apache License, Version 2.0 (the "License");
4680// you may not use this file except in compliance with the License.
4681// You may obtain a copy of the License at
4682//
4683// http://www.apache.org/licenses/LICENSE-2.0
4684//
4685// Unless required by applicable law or agreed to in writing, software
4686// distributed under the License is distributed on an "AS IS" BASIS,
4687// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4688// See the License for the specific language governing permissions and
4689// limitations under the License.