Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(19)

Side by Side Diff: Objects/codeobject.c

Issue 25843: lambdas on the same line may incorrectly share code objects
Patch Set: Created 4 years, 1 month ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Lib/test/test_compile.py ('k') | Python/compile.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #include "Python.h" 1 #include "Python.h"
2 #include "code.h" 2 #include "code.h"
3 #include "structmember.h" 3 #include "structmember.h"
4 4
5 #define NAME_CHARS \ 5 #define NAME_CHARS \
6 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz" 6 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
7 7
8 /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ 8 /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
9 9
10 static int 10 static int
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 lineno = -1; 400 lineno = -1;
401 if (co->co_filename && PyUnicode_Check(co->co_filename)) { 401 if (co->co_filename && PyUnicode_Check(co->co_filename)) {
402 return PyUnicode_FromFormat( 402 return PyUnicode_FromFormat(
403 "<code object %U at %p, file \"%U\", line %d>", 403 "<code object %U at %p, file \"%U\", line %d>",
404 co->co_name, co, co->co_filename, lineno); 404 co->co_name, co, co->co_filename, lineno);
405 } else { 405 } else {
406 return PyUnicode_FromFormat( 406 return PyUnicode_FromFormat(
407 "<code object %U at %p, file ???, line %d>", 407 "<code object %U at %p, file ???, line %d>",
408 co->co_name, co, lineno); 408 co->co_name, co, lineno);
409 } 409 }
410 }
411
412 PyObject*
413 _PyCode_ConstantKey(PyObject *op)
414 {
415 PyObject *key;
416
417 /* Py_None and Py_Ellipsis are singleton */
418 if (op == Py_None || op == Py_Ellipsis
419 || PyLong_CheckExact(op)
420 || PyBool_Check(op)
421 || PyBytes_CheckExact(op)
422 || PyUnicode_CheckExact(op)
423 /* code_richcompare() uses _PyCode_ConstantKey() internally */
424 || PyCode_Check(op)) {
425 key = PyTuple_Pack(2, Py_TYPE(op), op);
426 }
427 else if (PyFloat_CheckExact(op)) {
428 double d = PyFloat_AS_DOUBLE(op);
429 /* all we need is to make the tuple different in either the 0.0
430 * or -0.0 case from all others, just to avoid the "coercion".
431 */
432 if (d == 0.0 && copysign(1.0, d) < 0.0)
433 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
434 else
435 key = PyTuple_Pack(2, Py_TYPE(op), op);
436 }
437 else if (PyComplex_CheckExact(op)) {
438 Py_complex z;
439 int real_negzero, imag_negzero;
440 /* For the complex case we must make complex(x, 0.)
441 different from complex(x, -0.) and complex(0., y)
442 different from complex(-0., y), for any x and y.
443 All four complex zeros must be distinguished.*/
444 z = PyComplex_AsCComplex(op);
445 real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
446 imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
447 /* use True, False and None singleton as tags for the real and imag
448 * sign, to make tuples different */
449 if (real_negzero && imag_negzero) {
450 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_True);
451 }
452 else if (imag_negzero) {
453 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_False);
454 }
455 else if (real_negzero) {
456 key = PyTuple_Pack(3, Py_TYPE(op), op, Py_None);
457 }
458 else {
459 key = PyTuple_Pack(2, Py_TYPE(op), op);
460 }
461 }
462 else if (PyTuple_CheckExact(op)) {
463 Py_ssize_t i, len;
464 PyObject *tuple;
465
466 len = PyTuple_GET_SIZE(op);
467 tuple = PyTuple_New(len);
468 if (tuple == NULL)
469 return NULL;
470
471 for (i=0; i < len; i++) {
472 PyObject *item, *item_key;
473
474 item = PyTuple_GET_ITEM(op, i);
475 item_key = _PyCode_ConstantKey(item);
476 if (item_key == NULL) {
477 Py_DECREF(tuple);
478 return NULL;
479 }
480
481 PyTuple_SET_ITEM(tuple, i, item_key);
482 }
483
484 key = PyTuple_Pack(3, Py_TYPE(op), op, tuple);
485 Py_DECREF(tuple);
486 }
487 else if (PyFrozenSet_CheckExact(op)) {
488 Py_ssize_t pos = 0;
489 PyObject *item;
490 Py_hash_t hash;
491 Py_ssize_t i, len;
492 PyObject *tuple, *set;
493
494 len = PySet_GET_SIZE(op);
495 tuple = PyTuple_New(len);
496 if (tuple == NULL)
497 return NULL;
498
499 i = 0;
500 while (_PySet_NextEntry(op, &pos, &item, &hash)) {
501 PyObject *item_key;
502
503 item_key = _PyCode_ConstantKey(item);
504 if (item_key == NULL) {
505 Py_DECREF(tuple);
506 return NULL;
507 }
508
509 assert(i < len);
510 PyTuple_SET_ITEM(tuple, i, item_key);
511 i++;
512 }
513 set = PyFrozenSet_New(tuple);
514 Py_DECREF(tuple);
515 if (set == NULL)
516 return NULL;
517
518 key = PyTuple_Pack(3, Py_TYPE(op), op, set);
519 Py_DECREF(set);
520 return key;
521 }
522 else {
523 /* for other types, use the identifier to *not* merge them
524 * even if they are equal */
525 PyObject *obj_id = PyLong_FromVoidPtr(op);
526 if (obj_id == NULL)
527 return NULL;
528
529 key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id);
530 Py_DECREF(obj_id);
531 }
532 return key;
410 } 533 }
411 534
412 static PyObject * 535 static PyObject *
413 code_richcompare(PyObject *self, PyObject *other, int op) 536 code_richcompare(PyObject *self, PyObject *other, int op)
414 { 537 {
415 PyCodeObject *co, *cp; 538 PyCodeObject *co, *cp;
416 int eq; 539 int eq;
540 PyObject *consts1, *consts2;
417 PyObject *res; 541 PyObject *res;
418 542
419 if ((op != Py_EQ && op != Py_NE) || 543 if ((op != Py_EQ && op != Py_NE) ||
420 !PyCode_Check(self) || 544 !PyCode_Check(self) ||
421 !PyCode_Check(other)) { 545 !PyCode_Check(other)) {
422 Py_RETURN_NOTIMPLEMENTED; 546 Py_RETURN_NOTIMPLEMENTED;
423 } 547 }
424 548
425 co = (PyCodeObject *)self; 549 co = (PyCodeObject *)self;
426 cp = (PyCodeObject *)other; 550 cp = (PyCodeObject *)other;
427 551
428 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); 552 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
429 if (eq <= 0) goto unequal; 553 if (eq <= 0) goto unequal;
430 eq = co->co_argcount == cp->co_argcount; 554 eq = co->co_argcount == cp->co_argcount;
431 if (!eq) goto unequal; 555 if (!eq) goto unequal;
432 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; 556 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
433 if (!eq) goto unequal; 557 if (!eq) goto unequal;
434 eq = co->co_nlocals == cp->co_nlocals; 558 eq = co->co_nlocals == cp->co_nlocals;
435 if (!eq) goto unequal; 559 if (!eq) goto unequal;
436 eq = co->co_flags == cp->co_flags; 560 eq = co->co_flags == cp->co_flags;
437 if (!eq) goto unequal; 561 if (!eq) goto unequal;
438 eq = co->co_firstlineno == cp->co_firstlineno; 562 eq = co->co_firstlineno == cp->co_firstlineno;
439 if (!eq) goto unequal; 563 if (!eq) goto unequal;
440 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); 564 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
441 if (eq <= 0) goto unequal; 565 if (eq <= 0) goto unequal;
442 eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ); 566
567 /* compare constants */
568 consts1 = _PyCode_ConstantKey(co->co_consts);
569 if (!consts1)
570 return NULL;
571 consts2 = _PyCode_ConstantKey(cp->co_consts);
572 if (!consts2) {
573 Py_DECREF(consts1);
574 return NULL;
575 }
576 eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
577 Py_DECREF(consts1);
578 Py_DECREF(consts2);
443 if (eq <= 0) goto unequal; 579 if (eq <= 0) goto unequal;
580
444 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ); 581 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
445 if (eq <= 0) goto unequal; 582 if (eq <= 0) goto unequal;
446 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ); 583 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
447 if (eq <= 0) goto unequal; 584 if (eq <= 0) goto unequal;
448 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ); 585 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
449 if (eq <= 0) goto unequal; 586 if (eq <= 0) goto unequal;
450 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ); 587 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
451 if (eq <= 0) goto unequal; 588 if (eq <= 0) goto unequal;
452 589
453 if (op == Py_EQ) 590 if (op == Py_EQ)
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 p++; 745 p++;
609 } 746 }
610 bounds->ap_upper = addr; 747 bounds->ap_upper = addr;
611 } 748 }
612 else { 749 else {
613 bounds->ap_upper = INT_MAX; 750 bounds->ap_upper = INT_MAX;
614 } 751 }
615 752
616 return line; 753 return line;
617 } 754 }
OLDNEW
« no previous file with comments | « Lib/test/test_compile.py ('k') | Python/compile.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+