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

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)) {
storchaka 2015/12/14 18:23:18 May be use PyFloat_CheckExact?
haypo 2016/01/22 12:24:13 I only moved the code, I didn't write this part my
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);
storchaka 2015/12/14 18:23:18 May be use different tags None, True, False, nothi
haypo 2016/01/22 12:24:13 Ok, I used your suggestion.
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 {
478 key = PyTuple_Pack(2, o, o->ob_type);
479 }
480 return key;
410 } 481 }
411 482
412 static PyObject * 483 static PyObject *
413 code_richcompare(PyObject *self, PyObject *other, int op) 484 code_richcompare(PyObject *self, PyObject *other, int op)
414 { 485 {
415 PyCodeObject *co, *cp; 486 PyCodeObject *co, *cp;
416 int eq; 487 int eq;
488 PyObject *consts1, *consts2;
417 PyObject *res; 489 PyObject *res;
418 490
419 if ((op != Py_EQ && op != Py_NE) || 491 if ((op != Py_EQ && op != Py_NE) ||
420 !PyCode_Check(self) || 492 !PyCode_Check(self) ||
421 !PyCode_Check(other)) { 493 !PyCode_Check(other)) {
422 Py_RETURN_NOTIMPLEMENTED; 494 Py_RETURN_NOTIMPLEMENTED;
423 } 495 }
424 496
425 co = (PyCodeObject *)self; 497 co = (PyCodeObject *)self;
426 cp = (PyCodeObject *)other; 498 cp = (PyCodeObject *)other;
427 499
428 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ); 500 eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
429 if (eq <= 0) goto unequal; 501 if (eq <= 0) goto unequal;
430 eq = co->co_argcount == cp->co_argcount; 502 eq = co->co_argcount == cp->co_argcount;
431 if (!eq) goto unequal; 503 if (!eq) goto unequal;
432 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount; 504 eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
433 if (!eq) goto unequal; 505 if (!eq) goto unequal;
434 eq = co->co_nlocals == cp->co_nlocals; 506 eq = co->co_nlocals == cp->co_nlocals;
435 if (!eq) goto unequal; 507 if (!eq) goto unequal;
436 eq = co->co_flags == cp->co_flags; 508 eq = co->co_flags == cp->co_flags;
437 if (!eq) goto unequal; 509 if (!eq) goto unequal;
438 eq = co->co_firstlineno == cp->co_firstlineno; 510 eq = co->co_firstlineno == cp->co_firstlineno;
439 if (!eq) goto unequal; 511 if (!eq) goto unequal;
440 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ); 512 eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
441 if (eq <= 0) goto unequal; 513 if (eq <= 0) goto unequal;
442 eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ); 514
515 /* compare constants */
516 consts1 = _PyCode_ConstantKey(co->co_consts);
517 if (!consts1)
518 return NULL;
519 consts2 = _PyCode_ConstantKey(cp->co_consts);
520 if (!consts2) {
521 Py_DECREF(consts1);
522 return NULL;
523 }
524 eq = PyObject_RichCompareBool(consts1, consts2, Py_EQ);
525 Py_DECREF(consts1);
526 Py_DECREF(consts2);
443 if (eq <= 0) goto unequal; 527 if (eq <= 0) goto unequal;
528
444 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ); 529 eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
445 if (eq <= 0) goto unequal; 530 if (eq <= 0) goto unequal;
446 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ); 531 eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
447 if (eq <= 0) goto unequal; 532 if (eq <= 0) goto unequal;
448 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ); 533 eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
449 if (eq <= 0) goto unequal; 534 if (eq <= 0) goto unequal;
450 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ); 535 eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
451 if (eq <= 0) goto unequal; 536 if (eq <= 0) goto unequal;
452 537
453 if (op == Py_EQ) 538 if (op == Py_EQ)
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 break; 690 break;
606 } 691 }
607 bounds->ap_upper = addr; 692 bounds->ap_upper = addr;
608 } 693 }
609 else { 694 else {
610 bounds->ap_upper = INT_MAX; 695 bounds->ap_upper = INT_MAX;
611 } 696 }
612 697
613 return line; 698 return line;
614 } 699 }
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+