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

Side by Side Diff: Objects/codeobject.c

Issue 25843: lambdas on the same line may incorrectly share code objects
Patch Set: Created 4 years, 2 months 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 | « Include/code.h ('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 *o)
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(o)) {
420 double d = PyFloat_AS_DOUBLE(o);
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, o, o->ob_type, Py_None);
426 else
427 key = PyTuple_Pack(2, o, o->ob_type);
428 }
429 else if (PyComplex_Check(o)) {
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(o);
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, o, o->ob_type,
441 Py_None, Py_None, Py_None);
442 }
443 else if (imag_negzero) {
444 key = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
445 }
446 else if (real_negzero) {
447 key = PyTuple_Pack(3, o, o->ob_type, Py_None);
448 }
449 else {
450 key = PyTuple_Pack(2, o, o->ob_type);
451 }
452 }
453 else if (PyTuple_Check(o)) {
454 Py_ssize_t i, len;
455 PyObject *keys;
456
457 len = PyTuple_GET_SIZE(o);
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(o, 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, o, keys);
476 }
477 else if (PyAnySet_CheckExact(o)) {
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(o);
485 keys = PyTuple_New(len);
486 if (keys == NULL)
487 return NULL;
488
489 i = 0;
490 while (_PySet_NextEntry(o, &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 2015/12/14 20:29:30 Is it ever possible? If yes, we have more serious
haypo 2016/01/22 12:24:14 Ok, I replaced it with an assertion.
503 break;
504 }
505 }
506 return keys;
storchaka 2015/12/14 20:29:30 Just keys? Not wrap it in a tuple? And note that
haypo 2016/01/22 12:24:14 Ok, I will wrap the set inside a tuple, as other t
507 }
508 else {
509 key = PyTuple_Pack(2, o, o->ob_type);
510 }
511 return key;
410 } 512 }
411 513
412 static PyObject * 514 static PyObject *
413 code_richcompare(PyObject *self, PyObject *other, int op) 515 code_richcompare(PyObject *self, PyObject *other, int op)
414 { 516 {
415 PyCodeObject *co, *cp; 517 PyCodeObject *co, *cp;
416 int eq; 518 int eq;
519 PyObject *consts1, *consts2;
417 PyObject *res; 520 PyObject *res;
418 521
419 if ((op != Py_EQ && op != Py_NE) || 522 if ((op != Py_EQ && op != Py_NE) ||
420 !PyCode_Check(self) || 523 !PyCode_Check(self) ||
421 !PyCode_Check(other)) { 524 !PyCode_Check(other)) {
422 Py_RETURN_NOTIMPLEMENTED; 525 Py_RETURN_NOTIMPLEMENTED;
423 } 526 }
424 527
425 co = (PyCodeObject *)self; 528 co = (PyCodeObject *)self;
426 cp = (PyCodeObject *)other; 529 cp = (PyCodeObject *)other;
427 530
428 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); 531 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
429 if (eq <= 0) goto unequal; 532 if (eq <= 0) goto unequal;
430 eq = co->co_argcount == cp->co_argcount; 533 eq = co->co_argcount == cp->co_argcount;
431 if (!eq) goto unequal; 534 if (!eq) goto unequal;
432 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; 535 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
433 if (!eq) goto unequal; 536 if (!eq) goto unequal;
434 eq = co->co_nlocals == cp->co_nlocals; 537 eq = co->co_nlocals == cp->co_nlocals;
435 if (!eq) goto unequal; 538 if (!eq) goto unequal;
436 eq = co->co_flags == cp->co_flags; 539 eq = co->co_flags == cp->co_flags;
437 if (!eq) goto unequal; 540 if (!eq) goto unequal;
438 eq = co->co_firstlineno == cp->co_firstlineno; 541 eq = co->co_firstlineno == cp->co_firstlineno;
439 if (!eq) goto unequal; 542 if (!eq) goto unequal;
440 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); 543 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
441 if (eq <= 0) goto unequal; 544 if (eq <= 0) goto unequal;
442 eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ); 545
546 /* compare constants */
547 consts1 = _PyCode_ConstantKey(co->co_consts);
548 if (!consts1)
549 return NULL;
550 consts2 = _PyCode_ConstantKey(cp->co_consts);
551 if (!consts2) {
552 Py_DECREF(consts1);
553 return NULL;
554 }
555 eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
556 Py_DECREF(consts1);
557 Py_DECREF(consts2);
443 if (eq <= 0) goto unequal; 558 if (eq <= 0) goto unequal;
559
444 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ); 560 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
445 if (eq <= 0) goto unequal; 561 if (eq <= 0) goto unequal;
446 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ); 562 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
447 if (eq <= 0) goto unequal; 563 if (eq <= 0) goto unequal;
448 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ); 564 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
449 if (eq <= 0) goto unequal; 565 if (eq <= 0) goto unequal;
450 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ); 566 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
451 if (eq <= 0) goto unequal; 567 if (eq <= 0) goto unequal;
452 568
453 if (op == Py_EQ) 569 if (op == Py_EQ)
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 break; 721 break;
606 } 722 }
607 bounds->ap_upper = addr; 723 bounds->ap_upper = addr;
608 } 724 }
609 else { 725 else {
610 bounds->ap_upper = INT_MAX; 726 bounds->ap_upper = INT_MAX;
611 } 727 }
612 728
613 return line; 729 return line;
614 } 730 }
OLDNEW
« no previous file with comments | « Include/code.h ('k') | Python/compile.c » ('j') | no next file with comments »

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