You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

593 lines
19 KiB

Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........
17 years ago
Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........
17 years ago
Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........
17 years ago
Restructure comparison dramatically. There is no longer a default *ordering* between objects; there is only a default equality test (defined by an object being equal to itself only). Read the comment in object.c. The current implementation never uses a three-way comparison to compute a rich comparison, but it does use a rich comparison to compute a three-way comparison. I'm not quite done ripping out all the calls to PyObject_Compare/Cmp, or replacing tp_compare implementations with tp_richcompare implementations; but much of that has happened (to make most unit tests pass). The following tests still fail, because I need help deciding or understanding: test_codeop -- depends on comparing code objects test_datetime -- need Tim Peters' opinion test_marshal -- depends on comparing code objects test_mutants -- need help understanding it The problem with test_codeop and test_marshal is this: these tests compare two different code objects and expect them to be equal. Is that still a feature we'd like to support? I've temporarily removed the comparison and hash code from code objects, so they use the default (equality by pointer only) comparison. For the other two tests, run them to see for yourself. (There may be more failing test with "-u all".) A general problem with getting lots of these tests to pass is the reality that for object types that have a natural total ordering, implementing __cmp__ is much more convenient than implementing __eq__, __ne__, __lt__, and so on. Should we go back to allowing __cmp__ to provide a total ordering? Should we provide some other way to implement rich comparison with a single method override? Alex proposed a __key__() method; I've considered a __richcmp__() method. Or perhaps __cmp__() just shouldn't be killed off...
20 years ago
Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........
17 years ago
Merged revisions 72487-72488,72879 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r72487 | jeffrey.yasskin | 2009-05-08 17:51:06 -0400 (Fri, 08 May 2009) | 7 lines PyCode_NewEmpty: Most uses of PyCode_New found by http://www.google.com/codesearch?q=PyCode_New are trying to build an empty code object, usually to put it in a dummy frame object. This patch adds a PyCode_NewEmpty wrapper which lets the user specify just the filename, function name, and first line number, instead of also requiring lots of code internals. ........ r72488 | jeffrey.yasskin | 2009-05-08 18:23:21 -0400 (Fri, 08 May 2009) | 13 lines Issue 5954, PyFrame_GetLineNumber: Most uses of PyCode_Addr2Line (http://www.google.com/codesearch?q=PyCode_Addr2Line) are just trying to get the line number of a specified frame, but there's no way to do that directly. Forcing people to go through the code object makes them know more about the guts of the interpreter than they should need. The remaining uses of PyCode_Addr2Line seem to be getting the line from a traceback (for example, http://www.google.com/codesearch/p?hl=en#u_9_nDrchrw/pygame-1.7.1release/src/base.c&q=PyCode_Addr2Line), which is replaced by the tb_lineno field. So we may be able to deprecate PyCode_Addr2Line entirely for external use. ........ r72879 | jeffrey.yasskin | 2009-05-23 19:23:01 -0400 (Sat, 23 May 2009) | 14 lines Issue #6042: lnotab-based tracing is very complicated and isn't documented very well. There were at least 3 comment blocks purporting to document co_lnotab, and none did a very good job. This patch unifies them into Objects/lnotab_notes.txt which tries to completely capture the current state of affairs. I also discovered that we've attached 2 layers of patches to the basic tracing scheme. The first layer avoids jumping to instructions that don't start a line, to avoid problems in if statements and while loops. The second layer discovered that jumps backward do need to trace at instructions that don't start a line, so it added extra lnotab entries for 'while' and 'for' loops, and added a special case for backward jumps within the same line. I replaced these patches by just treating forward and backward jumps differently. ........
17 years ago
  1. #include "Python.h"
  2. #include "code.h"
  3. #include "structmember.h"
  4. #define NAME_CHARS \
  5. "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
  6. /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
  7. static int
  8. all_name_chars(PyObject *o)
  9. {
  10. static char ok_name_char[256];
  11. static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
  12. PyUnicodeObject *u = (PyUnicodeObject *)o;
  13. const unsigned char *s;
  14. if (!PyUnicode_Check(o) || PyUnicode_READY(u) == -1 ||
  15. PyUnicode_MAX_CHAR_VALUE(u) >= 128)
  16. return 0;
  17. if (ok_name_char[*name_chars] == 0) {
  18. unsigned char *p;
  19. for (p = name_chars; *p; p++)
  20. ok_name_char[*p] = 1;
  21. }
  22. s = PyUnicode_1BYTE_DATA(u);
  23. while (*s) {
  24. if (ok_name_char[*s++] == 0)
  25. return 0;
  26. }
  27. return 1;
  28. }
  29. static void
  30. intern_strings(PyObject *tuple)
  31. {
  32. Py_ssize_t i;
  33. for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
  34. PyObject *v = PyTuple_GET_ITEM(tuple, i);
  35. if (v == NULL || !PyUnicode_CheckExact(v)) {
  36. Py_FatalError("non-string found in code slot");
  37. }
  38. PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
  39. }
  40. }
  41. PyCodeObject *
  42. PyCode_New(int argcount, int kwonlyargcount,
  43. int nlocals, int stacksize, int flags,
  44. PyObject *code, PyObject *consts, PyObject *names,
  45. PyObject *varnames, PyObject *freevars, PyObject *cellvars,
  46. PyObject *filename, PyObject *name, int firstlineno,
  47. PyObject *lnotab)
  48. {
  49. PyCodeObject *co;
  50. unsigned char *cell2arg = NULL;
  51. Py_ssize_t i, n_cellvars;
  52. /* Check argument types */
  53. if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
  54. code == NULL ||
  55. consts == NULL || !PyTuple_Check(consts) ||
  56. names == NULL || !PyTuple_Check(names) ||
  57. varnames == NULL || !PyTuple_Check(varnames) ||
  58. freevars == NULL || !PyTuple_Check(freevars) ||
  59. cellvars == NULL || !PyTuple_Check(cellvars) ||
  60. name == NULL || !PyUnicode_Check(name) ||
  61. filename == NULL || !PyUnicode_Check(filename) ||
  62. lnotab == NULL || !PyBytes_Check(lnotab) ||
  63. !PyObject_CheckReadBuffer(code)) {
  64. PyErr_BadInternalCall();
  65. return NULL;
  66. }
  67. n_cellvars = PyTuple_GET_SIZE(cellvars);
  68. intern_strings(names);
  69. intern_strings(varnames);
  70. intern_strings(freevars);
  71. intern_strings(cellvars);
  72. /* Intern selected string constants */
  73. for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) {
  74. PyObject *v = PyTuple_GetItem(consts, i);
  75. if (!all_name_chars(v))
  76. continue;
  77. PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
  78. }
  79. /* Create mapping between cells and arguments if needed. */
  80. if (n_cellvars) {
  81. Py_ssize_t total_args = argcount + kwonlyargcount +
  82. ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
  83. Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars;
  84. int used_cell2arg = 0;
  85. cell2arg = PyMem_MALLOC(alloc_size);
  86. if (cell2arg == NULL)
  87. return NULL;
  88. memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size);
  89. /* Find cells which are also arguments. */
  90. for (i = 0; i < n_cellvars; i++) {
  91. Py_ssize_t j;
  92. PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
  93. for (j = 0; j < total_args; j++) {
  94. PyObject *arg = PyTuple_GET_ITEM(varnames, j);
  95. if (!PyUnicode_Compare(cell, arg)) {
  96. cell2arg[i] = j;
  97. used_cell2arg = 1;
  98. break;
  99. }
  100. }
  101. }
  102. if (!used_cell2arg) {
  103. PyMem_FREE(cell2arg);
  104. cell2arg = NULL;
  105. }
  106. }
  107. co = PyObject_NEW(PyCodeObject, &PyCode_Type);
  108. if (co == NULL) {
  109. if (cell2arg)
  110. PyMem_FREE(cell2arg);
  111. return NULL;
  112. }
  113. co->co_argcount = argcount;
  114. co->co_kwonlyargcount = kwonlyargcount;
  115. co->co_nlocals = nlocals;
  116. co->co_stacksize = stacksize;
  117. co->co_flags = flags;
  118. Py_INCREF(code);
  119. co->co_code = code;
  120. Py_INCREF(consts);
  121. co->co_consts = consts;
  122. Py_INCREF(names);
  123. co->co_names = names;
  124. Py_INCREF(varnames);
  125. co->co_varnames = varnames;
  126. Py_INCREF(freevars);
  127. co->co_freevars = freevars;
  128. Py_INCREF(cellvars);
  129. co->co_cellvars = cellvars;
  130. co->co_cell2arg = cell2arg;
  131. Py_INCREF(filename);
  132. co->co_filename = filename;
  133. Py_INCREF(name);
  134. co->co_name = name;
  135. co->co_firstlineno = firstlineno;
  136. Py_INCREF(lnotab);
  137. co->co_lnotab = lnotab;
  138. co->co_zombieframe = NULL;
  139. co->co_weakreflist = NULL;
  140. return co;
  141. }
  142. PyCodeObject *
  143. PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
  144. {
  145. static PyObject *emptystring = NULL;
  146. static PyObject *nulltuple = NULL;
  147. PyObject *filename_ob = NULL;
  148. PyObject *funcname_ob = NULL;
  149. PyCodeObject *result = NULL;
  150. if (emptystring == NULL) {
  151. emptystring = PyBytes_FromString("");
  152. if (emptystring == NULL)
  153. goto failed;
  154. }
  155. if (nulltuple == NULL) {
  156. nulltuple = PyTuple_New(0);
  157. if (nulltuple == NULL)
  158. goto failed;
  159. }
  160. funcname_ob = PyUnicode_FromString(funcname);
  161. if (funcname_ob == NULL)
  162. goto failed;
  163. filename_ob = PyUnicode_DecodeFSDefault(filename);
  164. if (filename_ob == NULL)
  165. goto failed;
  166. result = PyCode_New(0, /* argcount */
  167. 0, /* kwonlyargcount */
  168. 0, /* nlocals */
  169. 0, /* stacksize */
  170. 0, /* flags */
  171. emptystring, /* code */
  172. nulltuple, /* consts */
  173. nulltuple, /* names */
  174. nulltuple, /* varnames */
  175. nulltuple, /* freevars */
  176. nulltuple, /* cellvars */
  177. filename_ob, /* filename */
  178. funcname_ob, /* name */
  179. firstlineno, /* firstlineno */
  180. emptystring /* lnotab */
  181. );
  182. failed:
  183. Py_XDECREF(funcname_ob);
  184. Py_XDECREF(filename_ob);
  185. return result;
  186. }
  187. #define OFF(x) offsetof(PyCodeObject, x)
  188. static PyMemberDef code_memberlist[] = {
  189. {"co_argcount", T_INT, OFF(co_argcount), READONLY},
  190. {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY},
  191. {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
  192. {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
  193. {"co_flags", T_INT, OFF(co_flags), READONLY},
  194. {"co_code", T_OBJECT, OFF(co_code), READONLY},
  195. {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
  196. {"co_names", T_OBJECT, OFF(co_names), READONLY},
  197. {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
  198. {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
  199. {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
  200. {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
  201. {"co_name", T_OBJECT, OFF(co_name), READONLY},
  202. {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
  203. {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
  204. {NULL} /* Sentinel */
  205. };
  206. /* Helper for code_new: return a shallow copy of a tuple that is
  207. guaranteed to contain exact strings, by converting string subclasses
  208. to exact strings and complaining if a non-string is found. */
  209. static PyObject*
  210. validate_and_copy_tuple(PyObject *tup)
  211. {
  212. PyObject *newtuple;
  213. PyObject *item;
  214. Py_ssize_t i, len;
  215. len = PyTuple_GET_SIZE(tup);
  216. newtuple = PyTuple_New(len);
  217. if (newtuple == NULL)
  218. return NULL;
  219. for (i = 0; i < len; i++) {
  220. item = PyTuple_GET_ITEM(tup, i);
  221. if (PyUnicode_CheckExact(item)) {
  222. Py_INCREF(item);
  223. }
  224. else if (!PyUnicode_Check(item)) {
  225. PyErr_Format(
  226. PyExc_TypeError,
  227. "name tuples must contain only "
  228. "strings, not '%.500s'",
  229. item->ob_type->tp_name);
  230. Py_DECREF(newtuple);
  231. return NULL;
  232. }
  233. else {
  234. item = _PyUnicode_Copy(item);
  235. if (item == NULL) {
  236. Py_DECREF(newtuple);
  237. return NULL;
  238. }
  239. }
  240. PyTuple_SET_ITEM(newtuple, i, item);
  241. }
  242. return newtuple;
  243. }
  244. PyDoc_STRVAR(code_doc,
  245. "code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
  246. constants, names, varnames, filename, name, firstlineno,\n\
  247. lnotab[, freevars[, cellvars]])\n\
  248. \n\
  249. Create a code object. Not for the faint of heart.");
  250. static PyObject *
  251. code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  252. {
  253. int argcount;
  254. int kwonlyargcount;
  255. int nlocals;
  256. int stacksize;
  257. int flags;
  258. PyObject *co = NULL;
  259. PyObject *code;
  260. PyObject *consts;
  261. PyObject *names, *ournames = NULL;
  262. PyObject *varnames, *ourvarnames = NULL;
  263. PyObject *freevars = NULL, *ourfreevars = NULL;
  264. PyObject *cellvars = NULL, *ourcellvars = NULL;
  265. PyObject *filename;
  266. PyObject *name;
  267. int firstlineno;
  268. PyObject *lnotab;
  269. if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
  270. &argcount, &kwonlyargcount,
  271. &nlocals, &stacksize, &flags,
  272. &code,
  273. &PyTuple_Type, &consts,
  274. &PyTuple_Type, &names,
  275. &PyTuple_Type, &varnames,
  276. &filename, &name,
  277. &firstlineno, &lnotab,
  278. &PyTuple_Type, &freevars,
  279. &PyTuple_Type, &cellvars))
  280. return NULL;
  281. if (argcount < 0) {
  282. PyErr_SetString(
  283. PyExc_ValueError,
  284. "code: argcount must not be negative");
  285. goto cleanup;
  286. }
  287. if (kwonlyargcount < 0) {
  288. PyErr_SetString(
  289. PyExc_ValueError,
  290. "code: kwonlyargcount must not be negative");
  291. goto cleanup;
  292. }
  293. if (nlocals < 0) {
  294. PyErr_SetString(
  295. PyExc_ValueError,
  296. "code: nlocals must not be negative");
  297. goto cleanup;
  298. }
  299. ournames = validate_and_copy_tuple(names);
  300. if (ournames == NULL)
  301. goto cleanup;
  302. ourvarnames = validate_and_copy_tuple(varnames);
  303. if (ourvarnames == NULL)
  304. goto cleanup;
  305. if (freevars)
  306. ourfreevars = validate_and_copy_tuple(freevars);
  307. else
  308. ourfreevars = PyTuple_New(0);
  309. if (ourfreevars == NULL)
  310. goto cleanup;
  311. if (cellvars)
  312. ourcellvars = validate_and_copy_tuple(cellvars);
  313. else
  314. ourcellvars = PyTuple_New(0);
  315. if (ourcellvars == NULL)
  316. goto cleanup;
  317. co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
  318. nlocals, stacksize, flags,
  319. code, consts, ournames, ourvarnames,
  320. ourfreevars, ourcellvars, filename,
  321. name, firstlineno, lnotab);
  322. cleanup:
  323. Py_XDECREF(ournames);
  324. Py_XDECREF(ourvarnames);
  325. Py_XDECREF(ourfreevars);
  326. Py_XDECREF(ourcellvars);
  327. return co;
  328. }
  329. static void
  330. code_dealloc(PyCodeObject *co)
  331. {
  332. Py_XDECREF(co->co_code);
  333. Py_XDECREF(co->co_consts);
  334. Py_XDECREF(co->co_names);
  335. Py_XDECREF(co->co_varnames);
  336. Py_XDECREF(co->co_freevars);
  337. Py_XDECREF(co->co_cellvars);
  338. Py_XDECREF(co->co_filename);
  339. Py_XDECREF(co->co_name);
  340. Py_XDECREF(co->co_lnotab);
  341. if (co->co_cell2arg != NULL)
  342. PyMem_FREE(co->co_cell2arg);
  343. if (co->co_zombieframe != NULL)
  344. PyObject_GC_Del(co->co_zombieframe);
  345. if (co->co_weakreflist != NULL)
  346. PyObject_ClearWeakRefs((PyObject*)co);
  347. PyObject_DEL(co);
  348. }
  349. static PyObject *
  350. code_repr(PyCodeObject *co)
  351. {
  352. int lineno;
  353. if (co->co_firstlineno != 0)
  354. lineno = co->co_firstlineno;
  355. else
  356. lineno = -1;
  357. if (co->co_filename && PyUnicode_Check(co->co_filename)) {
  358. return PyUnicode_FromFormat(
  359. "<code object %U at %p, file \"%U\", line %d>",
  360. co->co_name, co, co->co_filename, lineno);
  361. } else {
  362. return PyUnicode_FromFormat(
  363. "<code object %U at %p, file ???, line %d>",
  364. co->co_name, co, lineno);
  365. }
  366. }
  367. static PyObject *
  368. code_richcompare(PyObject *self, PyObject *other, int op)
  369. {
  370. PyCodeObject *co, *cp;
  371. int eq;
  372. PyObject *res;
  373. if ((op != Py_EQ && op != Py_NE) ||
  374. !PyCode_Check(self) ||
  375. !PyCode_Check(other)) {
  376. Py_RETURN_NOTIMPLEMENTED;
  377. }
  378. co = (PyCodeObject *)self;
  379. cp = (PyCodeObject *)other;
  380. eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
  381. if (eq <= 0) goto unequal;
  382. eq = co->co_argcount == cp->co_argcount;
  383. if (!eq) goto unequal;
  384. eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
  385. if (!eq) goto unequal;
  386. eq = co->co_nlocals == cp->co_nlocals;
  387. if (!eq) goto unequal;
  388. eq = co->co_flags == cp->co_flags;
  389. if (!eq) goto unequal;
  390. eq = co->co_firstlineno == cp->co_firstlineno;
  391. if (!eq) goto unequal;
  392. eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
  393. if (eq <= 0) goto unequal;
  394. eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
  395. if (eq <= 0) goto unequal;
  396. eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
  397. if (eq <= 0) goto unequal;
  398. eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
  399. if (eq <= 0) goto unequal;
  400. eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
  401. if (eq <= 0) goto unequal;
  402. eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
  403. if (eq <= 0) goto unequal;
  404. if (op == Py_EQ)
  405. res = Py_True;
  406. else
  407. res = Py_False;
  408. goto done;
  409. unequal:
  410. if (eq < 0)
  411. return NULL;
  412. if (op == Py_NE)
  413. res = Py_True;
  414. else
  415. res = Py_False;
  416. done:
  417. Py_INCREF(res);
  418. return res;
  419. }
  420. static Py_hash_t
  421. code_hash(PyCodeObject *co)
  422. {
  423. Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
  424. h0 = PyObject_Hash(co->co_name);
  425. if (h0 == -1) return -1;
  426. h1 = PyObject_Hash(co->co_code);
  427. if (h1 == -1) return -1;
  428. h2 = PyObject_Hash(co->co_consts);
  429. if (h2 == -1) return -1;
  430. h3 = PyObject_Hash(co->co_names);
  431. if (h3 == -1) return -1;
  432. h4 = PyObject_Hash(co->co_varnames);
  433. if (h4 == -1) return -1;
  434. h5 = PyObject_Hash(co->co_freevars);
  435. if (h5 == -1) return -1;
  436. h6 = PyObject_Hash(co->co_cellvars);
  437. if (h6 == -1) return -1;
  438. h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
  439. co->co_argcount ^ co->co_kwonlyargcount ^
  440. co->co_nlocals ^ co->co_flags;
  441. if (h == -1) h = -2;
  442. return h;
  443. }
  444. /* XXX code objects need to participate in GC? */
  445. PyTypeObject PyCode_Type = {
  446. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  447. "code",
  448. sizeof(PyCodeObject),
  449. 0,
  450. (destructor)code_dealloc, /* tp_dealloc */
  451. 0, /* tp_print */
  452. 0, /* tp_getattr */
  453. 0, /* tp_setattr */
  454. 0, /* tp_reserved */
  455. (reprfunc)code_repr, /* tp_repr */
  456. 0, /* tp_as_number */
  457. 0, /* tp_as_sequence */
  458. 0, /* tp_as_mapping */
  459. (hashfunc)code_hash, /* tp_hash */
  460. 0, /* tp_call */
  461. 0, /* tp_str */
  462. PyObject_GenericGetAttr, /* tp_getattro */
  463. 0, /* tp_setattro */
  464. 0, /* tp_as_buffer */
  465. Py_TPFLAGS_DEFAULT, /* tp_flags */
  466. code_doc, /* tp_doc */
  467. 0, /* tp_traverse */
  468. 0, /* tp_clear */
  469. code_richcompare, /* tp_richcompare */
  470. offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
  471. 0, /* tp_iter */
  472. 0, /* tp_iternext */
  473. 0, /* tp_methods */
  474. code_memberlist, /* tp_members */
  475. 0, /* tp_getset */
  476. 0, /* tp_base */
  477. 0, /* tp_dict */
  478. 0, /* tp_descr_get */
  479. 0, /* tp_descr_set */
  480. 0, /* tp_dictoffset */
  481. 0, /* tp_init */
  482. 0, /* tp_alloc */
  483. code_new, /* tp_new */
  484. };
  485. /* Use co_lnotab to compute the line number from a bytecode index, addrq. See
  486. lnotab_notes.txt for the details of the lnotab representation.
  487. */
  488. int
  489. PyCode_Addr2Line(PyCodeObject *co, int addrq)
  490. {
  491. Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
  492. unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
  493. int line = co->co_firstlineno;
  494. int addr = 0;
  495. while (--size >= 0) {
  496. addr += *p++;
  497. if (addr > addrq)
  498. break;
  499. line += *p++;
  500. }
  501. return line;
  502. }
  503. /* Update *bounds to describe the first and one-past-the-last instructions in
  504. the same line as lasti. Return the number of that line. */
  505. int
  506. _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
  507. {
  508. Py_ssize_t size;
  509. int addr, line;
  510. unsigned char* p;
  511. p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
  512. size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
  513. addr = 0;
  514. line = co->co_firstlineno;
  515. assert(line > 0);
  516. /* possible optimization: if f->f_lasti == instr_ub
  517. (likely to be a common case) then we already know
  518. instr_lb -- if we stored the matching value of p
  519. somwhere we could skip the first while loop. */
  520. /* See lnotab_notes.txt for the description of
  521. co_lnotab. A point to remember: increments to p
  522. come in (addr, line) pairs. */
  523. bounds->ap_lower = 0;
  524. while (size > 0) {
  525. if (addr + *p > lasti)
  526. break;
  527. addr += *p++;
  528. if (*p)
  529. bounds->ap_lower = addr;
  530. line += *p++;
  531. --size;
  532. }
  533. if (size > 0) {
  534. while (--size >= 0) {
  535. addr += *p++;
  536. if (*p++)
  537. break;
  538. }
  539. bounds->ap_upper = addr;
  540. }
  541. else {
  542. bounds->ap_upper = INT_MAX;
  543. }
  544. return line;
  545. }