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

Side by Side Diff: Python/compile.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 | « Objects/codeobject.c ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file compiles an abstract syntax tree (AST) into Python bytecode. 2 * This file compiles an abstract syntax tree (AST) into Python bytecode.
3 * 3 *
4 * The primary entry point is PyAST_Compile(), which returns a 4 * The primary entry point is PyAST_Compile(), which returns a
5 * PyCodeObject. The compiler makes several passes to build the code 5 * PyCodeObject. The compiler makes several passes to build the code
6 * object: 6 * object:
7 * 1. Checks for future statements. See future.c 7 * 1. Checks for future statements. See future.c
8 * 2. Builds a symbol table. See symtable.c. 8 * 2. Builds a symbol table. See symtable.c.
9 * 3. Generate code for basic blocks. See compiler_mod() in this file. 9 * 3. Generate code for basic blocks. See compiler_mod() in this file.
10 * 4. Assemble the basic blocks into final code. See assemble() in 10 * 4. Assemble the basic blocks into final code. See assemble() in
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 if (!dict) return NULL; 386 if (!dict) return NULL;
387 387
388 n = PyList_Size(list); 388 n = PyList_Size(list);
389 for (i = 0; i < n; i++) { 389 for (i = 0; i < n; i++) {
390 v = PyLong_FromSsize_t(i); 390 v = PyLong_FromSsize_t(i);
391 if (!v) { 391 if (!v) {
392 Py_DECREF(dict); 392 Py_DECREF(dict);
393 return NULL; 393 return NULL;
394 } 394 }
395 k = PyList_GET_ITEM(list, i); 395 k = PyList_GET_ITEM(list, i);
396 k = PyTuple_Pack(2, k, k->ob_type); 396 k = _PyCode_ConstantKey(k);
397 if (k == NULL || PyDict_SetItem(dict, k, v) < 0) { 397 if (k == NULL || PyDict_SetItem(dict, k, v) < 0) {
398 Py_XDECREF(k); 398 Py_XDECREF(k);
399 Py_DECREF(v); 399 Py_DECREF(v);
400 Py_DECREF(dict); 400 Py_DECREF(dict);
401 return NULL; 401 return NULL;
402 } 402 }
403 Py_DECREF(k); 403 Py_DECREF(k);
404 Py_DECREF(v); 404 Py_DECREF(v);
405 } 405 }
406 return dict; 406 return dict;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
449 scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK; 449 scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
450 450
451 if (scope == scope_type || vi & flag) { 451 if (scope == scope_type || vi & flag) {
452 PyObject *tuple, *item = PyLong_FromSsize_t(i); 452 PyObject *tuple, *item = PyLong_FromSsize_t(i);
453 if (item == NULL) { 453 if (item == NULL) {
454 Py_DECREF(sorted_keys); 454 Py_DECREF(sorted_keys);
455 Py_DECREF(dest); 455 Py_DECREF(dest);
456 return NULL; 456 return NULL;
457 } 457 }
458 i++; 458 i++;
459 tuple = PyTuple_Pack(2, k, k->ob_type); 459 tuple = _PyCode_ConstantKey(k);
460 if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) { 460 if (!tuple || PyDict_SetItem(dest, tuple, item) < 0) {
461 Py_DECREF(sorted_keys); 461 Py_DECREF(sorted_keys);
462 Py_DECREF(item); 462 Py_DECREF(item);
463 Py_DECREF(dest); 463 Py_DECREF(dest);
464 Py_XDECREF(tuple); 464 Py_XDECREF(tuple);
465 return NULL; 465 return NULL;
466 } 466 }
467 Py_DECREF(item); 467 Py_DECREF(item);
468 Py_DECREF(tuple); 468 Py_DECREF(tuple);
469 } 469 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 _Py_IDENTIFIER(__class__); 552 _Py_IDENTIFIER(__class__);
553 PyObject *tuple, *name, *zero; 553 PyObject *tuple, *name, *zero;
554 int res; 554 int res;
555 assert(u->u_scope_type == COMPILER_SCOPE_CLASS); 555 assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
556 assert(PyDict_Size(u->u_cellvars) == 0); 556 assert(PyDict_Size(u->u_cellvars) == 0);
557 name = _PyUnicode_FromId(&PyId___class__); 557 name = _PyUnicode_FromId(&PyId___class__);
558 if (!name) { 558 if (!name) {
559 compiler_unit_free(u); 559 compiler_unit_free(u);
560 return 0; 560 return 0;
561 } 561 }
562 tuple = PyTuple_Pack(2, name, Py_TYPE(name)); 562 tuple = _PyCode_ConstantKey(name);
563 if (!tuple) { 563 if (!tuple) {
564 compiler_unit_free(u); 564 compiler_unit_free(u);
565 return 0; 565 return 0;
566 } 566 }
567 zero = PyLong_FromLong(0); 567 zero = PyLong_FromLong(0);
568 if (!zero) { 568 if (!zero) {
569 Py_DECREF(tuple); 569 Py_DECREF(tuple);
570 compiler_unit_free(u); 570 compiler_unit_free(u);
571 return 0; 571 return 0;
572 } 572 }
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
1098 b->b_return = 1; 1098 b->b_return = 1;
1099 compiler_set_lineno(c, off); 1099 compiler_set_lineno(c, off);
1100 return 1; 1100 return 1;
1101 } 1101 }
1102 1102
1103 static Py_ssize_t 1103 static Py_ssize_t
1104 compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o) 1104 compiler_add_o(struct compiler *c, PyObject *dict, PyObject *o)
1105 { 1105 {
1106 PyObject *t, *v; 1106 PyObject *t, *v;
1107 Py_ssize_t arg; 1107 Py_ssize_t arg;
1108 double d;
1109 1108
1110 /* necessary to make sure types aren't coerced (e.g., float and complex) */ 1109 t = _PyCode_ConstantKey(o);
1111 /* _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms */
1112 if (PyFloat_Check(o)) {
1113 d = PyFloat_AS_DOUBLE(o);
1114 /* all we need is to make the tuple different in either the 0.0
1115 * or -0.0 case from all others, just to avoid the "coercion".
1116 */
1117 if (d == 0.0 && copysign(1.0, d) < 0.0)
1118 t = PyTuple_Pack(3, o, o->ob_type, Py_None);
1119 else
1120 t = PyTuple_Pack(2, o, o->ob_type);
1121 }
1122 else if (PyComplex_Check(o)) {
1123 Py_complex z;
1124 int real_negzero, imag_negzero;
1125 /* For the complex case we must make complex(x, 0.)
1126 different from complex(x, -0.) and complex(0., y)
1127 different from complex(-0., y), for any x and y.
1128 All four complex zeros must be distinguished.*/
1129 z = PyComplex_AsCComplex(o);
1130 real_negzero = z.real == 0.0 && copysign(1.0, z.real) < 0.0;
1131 imag_negzero = z.imag == 0.0 && copysign(1.0, z.imag) < 0.0;
1132 if (real_negzero && imag_negzero) {
1133 t = PyTuple_Pack(5, o, o->ob_type,
1134 Py_None, Py_None, Py_None);
1135 }
1136 else if (imag_negzero) {
1137 t = PyTuple_Pack(4, o, o->ob_type, Py_None, Py_None);
1138 }
1139 else if (real_negzero) {
1140 t = PyTuple_Pack(3, o, o->ob_type, Py_None);
1141 }
1142 else {
1143 t = PyTuple_Pack(2, o, o->ob_type);
1144 }
1145 }
1146 else {
1147 t = PyTuple_Pack(2, o, o->ob_type);
1148 }
1149 if (t == NULL) 1110 if (t == NULL)
1150 return -1; 1111 return -1;
1151 1112
1152 v = PyDict_GetItem(dict, t); 1113 v = PyDict_GetItem(dict, t);
1153 if (!v) { 1114 if (!v) {
1154 if (PyErr_Occurred()) { 1115 if (PyErr_Occurred()) {
1155 Py_DECREF(t); 1116 Py_DECREF(t);
1156 return -1; 1117 return -1;
1157 } 1118 }
1158 arg = PyDict_Size(dict); 1119 arg = PyDict_Size(dict);
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
1452 Py_FatalError(buf); 1413 Py_FatalError(buf);
1453 } 1414 }
1454 1415
1455 return scope; 1416 return scope;
1456 } 1417 }
1457 1418
1458 static int 1419 static int
1459 compiler_lookup_arg(PyObject *dict, PyObject *name) 1420 compiler_lookup_arg(PyObject *dict, PyObject *name)
1460 { 1421 {
1461 PyObject *k, *v; 1422 PyObject *k, *v;
1462 k = PyTuple_Pack(2, name, name->ob_type); 1423 k = _PyCode_ConstantKey(name);
1463 if (k == NULL) 1424 if (k == NULL)
1464 return -1; 1425 return -1;
1465 v = PyDict_GetItem(dict, k); 1426 v = PyDict_GetItem(dict, k);
1466 Py_DECREF(k); 1427 Py_DECREF(k);
1467 if (v == NULL) 1428 if (v == NULL)
1468 return -1; 1429 return -1;
1469 return PyLong_AS_LONG(v); 1430 return PyLong_AS_LONG(v);
1470 } 1431 }
1471 1432
1472 static int 1433 static int
(...skipping 3177 matching lines...) Expand 10 before | Expand all | Expand 10 after
4650 dict_keys_inorder(PyObject *dict, Py_ssize_t offset) 4611 dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
4651 { 4612 {
4652 PyObject *tuple, *k, *v; 4613 PyObject *tuple, *k, *v;
4653 Py_ssize_t i, pos = 0, size = PyDict_Size(dict); 4614 Py_ssize_t i, pos = 0, size = PyDict_Size(dict);
4654 4615
4655 tuple = PyTuple_New(size); 4616 tuple = PyTuple_New(size);
4656 if (tuple == NULL) 4617 if (tuple == NULL)
4657 return NULL; 4618 return NULL;
4658 while (PyDict_Next(dict, &pos, &k, &v)) { 4619 while (PyDict_Next(dict, &pos, &k, &v)) {
4659 i = PyLong_AS_LONG(v); 4620 i = PyLong_AS_LONG(v);
4660 /* The keys of the dictionary are tuples. (see compiler_add_o) 4621 /* The keys of the dictionary are tuples. (see compiler_add_o
4661 The object we want is always first, though. */ 4622 * and _PyCode_ConstantKey). The object we want is always second,
4662 k = PyTuple_GET_ITEM(k, 0); 4623 * though. */
4624 k = PyTuple_GET_ITEM(k, 1);
4663 Py_INCREF(k); 4625 Py_INCREF(k);
4664 assert((i - offset) < size); 4626 assert((i - offset) < size);
4665 assert((i - offset) >= 0); 4627 assert((i - offset) >= 0);
4666 PyTuple_SET_ITEM(tuple, i - offset, k); 4628 PyTuple_SET_ITEM(tuple, i - offset, k);
4667 } 4629 }
4668 return tuple; 4630 return tuple;
4669 } 4631 }
4670 4632
4671 static int 4633 static int
4672 compute_code_flags(struct compiler *c) 4634 compute_code_flags(struct compiler *c)
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
4871 return co; 4833 return co;
4872 } 4834 }
4873 4835
4874 #undef PyAST_Compile 4836 #undef PyAST_Compile
4875 PyAPI_FUNC(PyCodeObject *) 4837 PyAPI_FUNC(PyCodeObject *)
4876 PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags, 4838 PyAST_Compile(mod_ty mod, const char *filename, PyCompilerFlags *flags,
4877 PyArena *arena) 4839 PyArena *arena)
4878 { 4840 {
4879 return PyAST_CompileEx(mod, filename, flags, -1, arena); 4841 return PyAST_CompileEx(mod, filename, flags, -1, arena);
4880 } 4842 }
OLDNEW
« no previous file with comments | « Objects/codeobject.c ('k') | no next file » | no next file with comments »

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