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

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
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 /* necessary to make sure types aren't coerced (e.g., float and complex)
418 * _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
419 if (PyFloat_Check(op)) {
storchaka 2016/01/20 19:19:01 See my comments to previous patches.
420 double d = PyFloat_AS_DOUBLE(op);
421 /* all we need is to make the tuple different in either the 0.0
422 * or -0.0 case from all others, just to avoid the "coercion".
423 */
424 if (d == 0.0 && copysign(1.0, d) < 0.0)
425 key = PyTuple_Pack(3, op, Py_TYPE(op), Py_None);
426 else
427 key = PyTuple_Pack(2, op, Py_TYPE(op));
428 }
429 else if (PyComplex_Check(op)) {
430 Py_complex z;
431 int real_negzero, imag_negzero;
432 /* For the complex case we must make complex(x, 0.)
433 different from complex(x, -0.) and complex(0., y)
434 different from complex(-0., y), for any x and y.
435 All four complex zeros must be distinguished.*/
436 z = PyComplex_AsCComplex(op);
437 real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
438 imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
439 if (real_negzero && imag_negzero) {
440 key = PyTuple_Pack(5, op, Py_TYPE(op),
storchaka 2016/01/20 19:19:01 See my comments to previous patches.
441 Py_None, Py_None, Py_None);
442 }
443 else if (imag_negzero) {
444 key = PyTuple_Pack(4, op, Py_TYPE(op), Py_None, Py_None);
445 }
446 else if (real_negzero) {
447 key = PyTuple_Pack(3, op, Py_TYPE(op), Py_None);
448 }
449 else {
450 key = PyTuple_Pack(2, op, Py_TYPE(op));
451 }
452 }
453 else if (PyTuple_Check(op)) {
454 Py_ssize_t i, len;
455 PyObject *keys;
456
457 len = PyTuple_GET_SIZE(op);
458 keys = PyTuple_New(len);
459 if (keys == NULL)
460 return NULL;
461
462 for (i=0; i < len; i++) {
463 PyObject *item, *item_key;
464
465 item = PyTuple_GET_ITEM(op, i);
466 item_key = _PyCode_ConstantKey(item);
467 if (item_key == NULL) {
468 Py_DECREF(keys);
469 return NULL;
470 }
471
472 PyTuple_SET_ITEM(keys, i, item_key);
473 }
474
475 key = PyTuple_Pack(2, op, keys);
476 }
477 else if (PyAnySet_CheckExact(op)) {
storchaka 2016/01/20 19:19:01 Accepts set.
478 Py_ssize_t pos = 0;
479 PyObject *item;
480 Py_hash_t hash;
481 Py_ssize_t i, len;
482 PyObject *keys;
483
484 len = PySet_GET_SIZE(op);
485 keys = PyTuple_New(len);
486 if (keys == NULL)
487 return NULL;
488
489 i = 0;
490 while (_PySet_NextEntry(op, &pos, &item, &hash)) {
491 PyObject *item_key;
492
493 item_key = _PyCode_ConstantKey(item);
494 if (item_key == NULL) {
495 Py_DECREF(keys);
496 return NULL;
497 }
498
499 PyTuple_SET_ITEM(keys, i, item_key);
500 i++;
501 if (i >= len) {
502 /* set size changed during iteration, ignore */
storchaka 2016/01/20 19:19:01 See my comments to previous patches. I think it is
503 break;
504 }
505 }
506 return keys;
storchaka 2016/01/20 19:19:01 See my comments to previous patches.
507 }
508 /* Py_None and Py_Ellipsis are singleton */
509 else if (op == Py_None || op == Py_Ellipsis
510 || PyLong_CheckExact(op)
511 || PyBool_Check(op)
512 || PyBytes_CheckExact(op)
513 || PyUnicode_CheckExact(op)
514 /* code_richcompare() uses _PyCode_ConstantKey() internally */
515 || PyCode_Check(op)) {
516 key = PyTuple_Pack(2, op, Py_TYPE(op));
517 }
518 else {
519 /* for other types, use the identifier to *not* merge them
520 * even if they are equal */
521 PyObject *obj_id = PyLong_FromVoidPtr(op);
522 if (obj_id == NULL)
523 return NULL;
524 key = PyTuple_Pack(3, op, Py_TYPE(op), obj_id);
525 Py_DECREF(obj_id);
526 }
527 return key;
410 } 528 }
411 529
412 static PyObject * 530 static PyObject *
413 code_richcompare(PyObject *self, PyObject *other, int op) 531 code_richcompare(PyObject *self, PyObject *other, int op)
414 { 532 {
415 PyCodeObject *co, *cp; 533 PyCodeObject *co, *cp;
416 int eq; 534 int eq;
535 PyObject *consts1, *consts2;
417 PyObject *res; 536 PyObject *res;
418 537
419 if ((op != Py_EQ && op != Py_NE) || 538 if ((op != Py_EQ && op != Py_NE) ||
420 !PyCode_Check(self) || 539 !PyCode_Check(self) ||
421 !PyCode_Check(other)) { 540 !PyCode_Check(other)) {
422 Py_RETURN_NOTIMPLEMENTED; 541 Py_RETURN_NOTIMPLEMENTED;
423 } 542 }
424 543
425 co = (PyCodeObject *)self; 544 co = (PyCodeObject *)self;
426 cp = (PyCodeObject *)other; 545 cp = (PyCodeObject *)other;
427 546
428 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); 547 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
429 if (eq <= 0) goto unequal; 548 if (eq <= 0) goto unequal;
430 eq = co->co_argcount == cp->co_argcount; 549 eq = co->co_argcount == cp->co_argcount;
431 if (!eq) goto unequal; 550 if (!eq) goto unequal;
432 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; 551 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
433 if (!eq) goto unequal; 552 if (!eq) goto unequal;
434 eq = co->co_nlocals == cp->co_nlocals; 553 eq = co->co_nlocals == cp->co_nlocals;
435 if (!eq) goto unequal; 554 if (!eq) goto unequal;
436 eq = co->co_flags == cp->co_flags; 555 eq = co->co_flags == cp->co_flags;
437 if (!eq) goto unequal; 556 if (!eq) goto unequal;
438 eq = co->co_firstlineno == cp->co_firstlineno; 557 eq = co->co_firstlineno == cp->co_firstlineno;
439 if (!eq) goto unequal; 558 if (!eq) goto unequal;
440 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); 559 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
441 if (eq <= 0) goto unequal; 560 if (eq <= 0) goto unequal;
442 eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ); 561
562 /* compare constants */
563 consts1 = _PyCode_ConstantKey(co->co_consts);
564 if (!consts1)
565 return NULL;
566 consts2 = _PyCode_ConstantKey(cp->co_consts);
567 if (!consts2) {
568 Py_DECREF(consts1);
569 return NULL;
570 }
571 eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
572 Py_DECREF(consts1);
573 Py_DECREF(consts2);
443 if (eq <= 0) goto unequal; 574 if (eq <= 0) goto unequal;
575
444 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ); 576 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
445 if (eq <= 0) goto unequal; 577 if (eq <= 0) goto unequal;
446 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ); 578 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
447 if (eq <= 0) goto unequal; 579 if (eq <= 0) goto unequal;
448 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ); 580 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
449 if (eq <= 0) goto unequal; 581 if (eq <= 0) goto unequal;
450 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ); 582 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
451 if (eq <= 0) goto unequal; 583 if (eq <= 0) goto unequal;
452 584
453 if (op == Py_EQ) 585 if (op == Py_EQ)
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 p++; 740 p++;
609 } 741 }
610 bounds->ap_upper = addr; 742 bounds->ap_upper = addr;
611 } 743 }
612 else { 744 else {
613 bounds->ap_upper = INT_MAX; 745 bounds->ap_upper = INT_MAX;
614 } 746 }
615 747
616 return line; 748 return line;
617 } 749 }
OLDNEW
« Lib/test/test_compile.py ('K') | « 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+