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.

557 lines
18 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(Py_UNICODE *s)
  9. {
  10. static char ok_name_char[256];
  11. static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
  12. if (ok_name_char[*name_chars] == 0) {
  13. unsigned char *p;
  14. for (p = name_chars; *p; p++)
  15. ok_name_char[*p] = 1;
  16. }
  17. while (*s) {
  18. if (*s >= 128)
  19. return 0;
  20. if (ok_name_char[*s++] == 0)
  21. return 0;
  22. }
  23. return 1;
  24. }
  25. static void
  26. intern_strings(PyObject *tuple)
  27. {
  28. Py_ssize_t i;
  29. for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
  30. PyObject *v = PyTuple_GET_ITEM(tuple, i);
  31. if (v == NULL || !PyUnicode_CheckExact(v)) {
  32. Py_FatalError("non-string found in code slot");
  33. }
  34. PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
  35. }
  36. }
  37. PyCodeObject *
  38. PyCode_New(int argcount, int kwonlyargcount,
  39. int nlocals, int stacksize, int flags,
  40. PyObject *code, PyObject *consts, PyObject *names,
  41. PyObject *varnames, PyObject *freevars, PyObject *cellvars,
  42. PyObject *filename, PyObject *name, int firstlineno,
  43. PyObject *lnotab)
  44. {
  45. PyCodeObject *co;
  46. Py_ssize_t i;
  47. /* Check argument types */
  48. if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 ||
  49. code == NULL ||
  50. consts == NULL || !PyTuple_Check(consts) ||
  51. names == NULL || !PyTuple_Check(names) ||
  52. varnames == NULL || !PyTuple_Check(varnames) ||
  53. freevars == NULL || !PyTuple_Check(freevars) ||
  54. cellvars == NULL || !PyTuple_Check(cellvars) ||
  55. name == NULL || !PyUnicode_Check(name) ||
  56. filename == NULL || !PyUnicode_Check(filename) ||
  57. lnotab == NULL || !PyBytes_Check(lnotab) ||
  58. !PyObject_CheckReadBuffer(code)) {
  59. PyErr_BadInternalCall();
  60. return NULL;
  61. }
  62. intern_strings(names);
  63. intern_strings(varnames);
  64. intern_strings(freevars);
  65. intern_strings(cellvars);
  66. /* Intern selected string constants */
  67. for (i = PyTuple_Size(consts); --i >= 0; ) {
  68. PyObject *v = PyTuple_GetItem(consts, i);
  69. if (!PyUnicode_Check(v))
  70. continue;
  71. if (!all_name_chars(PyUnicode_AS_UNICODE(v)))
  72. continue;
  73. PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
  74. }
  75. co = PyObject_NEW(PyCodeObject, &PyCode_Type);
  76. if (co != NULL) {
  77. co->co_argcount = argcount;
  78. co->co_kwonlyargcount = kwonlyargcount;
  79. co->co_nlocals = nlocals;
  80. co->co_stacksize = stacksize;
  81. co->co_flags = flags;
  82. Py_INCREF(code);
  83. co->co_code = code;
  84. Py_INCREF(consts);
  85. co->co_consts = consts;
  86. Py_INCREF(names);
  87. co->co_names = names;
  88. Py_INCREF(varnames);
  89. co->co_varnames = varnames;
  90. Py_INCREF(freevars);
  91. co->co_freevars = freevars;
  92. Py_INCREF(cellvars);
  93. co->co_cellvars = cellvars;
  94. Py_INCREF(filename);
  95. co->co_filename = filename;
  96. Py_INCREF(name);
  97. co->co_name = name;
  98. co->co_firstlineno = firstlineno;
  99. Py_INCREF(lnotab);
  100. co->co_lnotab = lnotab;
  101. co->co_zombieframe = NULL;
  102. co->co_weakreflist = NULL;
  103. }
  104. return co;
  105. }
  106. PyCodeObject *
  107. PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
  108. {
  109. static PyObject *emptystring = NULL;
  110. static PyObject *nulltuple = NULL;
  111. PyObject *filename_ob = NULL;
  112. PyObject *funcname_ob = NULL;
  113. PyCodeObject *result = NULL;
  114. if (emptystring == NULL) {
  115. emptystring = PyBytes_FromString("");
  116. if (emptystring == NULL)
  117. goto failed;
  118. }
  119. if (nulltuple == NULL) {
  120. nulltuple = PyTuple_New(0);
  121. if (nulltuple == NULL)
  122. goto failed;
  123. }
  124. funcname_ob = PyUnicode_FromString(funcname);
  125. if (funcname_ob == NULL)
  126. goto failed;
  127. filename_ob = PyUnicode_DecodeFSDefault(filename);
  128. if (filename_ob == NULL)
  129. goto failed;
  130. result = PyCode_New(0, /* argcount */
  131. 0, /* kwonlyargcount */
  132. 0, /* nlocals */
  133. 0, /* stacksize */
  134. 0, /* flags */
  135. emptystring, /* code */
  136. nulltuple, /* consts */
  137. nulltuple, /* names */
  138. nulltuple, /* varnames */
  139. nulltuple, /* freevars */
  140. nulltuple, /* cellvars */
  141. filename_ob, /* filename */
  142. funcname_ob, /* name */
  143. firstlineno, /* firstlineno */
  144. emptystring /* lnotab */
  145. );
  146. failed:
  147. Py_XDECREF(funcname_ob);
  148. Py_XDECREF(filename_ob);
  149. return result;
  150. }
  151. #define OFF(x) offsetof(PyCodeObject, x)
  152. static PyMemberDef code_memberlist[] = {
  153. {"co_argcount", T_INT, OFF(co_argcount), READONLY},
  154. {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY},
  155. {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
  156. {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
  157. {"co_flags", T_INT, OFF(co_flags), READONLY},
  158. {"co_code", T_OBJECT, OFF(co_code), READONLY},
  159. {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
  160. {"co_names", T_OBJECT, OFF(co_names), READONLY},
  161. {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
  162. {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
  163. {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
  164. {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
  165. {"co_name", T_OBJECT, OFF(co_name), READONLY},
  166. {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
  167. {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
  168. {NULL} /* Sentinel */
  169. };
  170. /* Helper for code_new: return a shallow copy of a tuple that is
  171. guaranteed to contain exact strings, by converting string subclasses
  172. to exact strings and complaining if a non-string is found. */
  173. static PyObject*
  174. validate_and_copy_tuple(PyObject *tup)
  175. {
  176. PyObject *newtuple;
  177. PyObject *item;
  178. Py_ssize_t i, len;
  179. len = PyTuple_GET_SIZE(tup);
  180. newtuple = PyTuple_New(len);
  181. if (newtuple == NULL)
  182. return NULL;
  183. for (i = 0; i < len; i++) {
  184. item = PyTuple_GET_ITEM(tup, i);
  185. if (PyUnicode_CheckExact(item)) {
  186. Py_INCREF(item);
  187. }
  188. else if (!PyUnicode_Check(item)) {
  189. PyErr_Format(
  190. PyExc_TypeError,
  191. "name tuples must contain only "
  192. "strings, not '%.500s'",
  193. item->ob_type->tp_name);
  194. Py_DECREF(newtuple);
  195. return NULL;
  196. }
  197. else {
  198. item = PyUnicode_FromUnicode(
  199. PyUnicode_AS_UNICODE(item),
  200. PyUnicode_GET_SIZE(item));
  201. if (item == NULL) {
  202. Py_DECREF(newtuple);
  203. return NULL;
  204. }
  205. }
  206. PyTuple_SET_ITEM(newtuple, i, item);
  207. }
  208. return newtuple;
  209. }
  210. PyDoc_STRVAR(code_doc,
  211. "code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
  212. constants, names, varnames, filename, name, firstlineno,\n\
  213. lnotab[, freevars[, cellvars]])\n\
  214. \n\
  215. Create a code object. Not for the faint of heart.");
  216. static PyObject *
  217. code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
  218. {
  219. int argcount;
  220. int kwonlyargcount;
  221. int nlocals;
  222. int stacksize;
  223. int flags;
  224. PyObject *co = NULL;
  225. PyObject *code;
  226. PyObject *consts;
  227. PyObject *names, *ournames = NULL;
  228. PyObject *varnames, *ourvarnames = NULL;
  229. PyObject *freevars = NULL, *ourfreevars = NULL;
  230. PyObject *cellvars = NULL, *ourcellvars = NULL;
  231. PyObject *filename;
  232. PyObject *name;
  233. int firstlineno;
  234. PyObject *lnotab;
  235. if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
  236. &argcount, &kwonlyargcount,
  237. &nlocals, &stacksize, &flags,
  238. &code,
  239. &PyTuple_Type, &consts,
  240. &PyTuple_Type, &names,
  241. &PyTuple_Type, &varnames,
  242. &filename, &name,
  243. &firstlineno, &lnotab,
  244. &PyTuple_Type, &freevars,
  245. &PyTuple_Type, &cellvars))
  246. return NULL;
  247. if (argcount < 0) {
  248. PyErr_SetString(
  249. PyExc_ValueError,
  250. "code: argcount must not be negative");
  251. goto cleanup;
  252. }
  253. if (kwonlyargcount < 0) {
  254. PyErr_SetString(
  255. PyExc_ValueError,
  256. "code: kwonlyargcount must not be negative");
  257. goto cleanup;
  258. }
  259. if (nlocals < 0) {
  260. PyErr_SetString(
  261. PyExc_ValueError,
  262. "code: nlocals must not be negative");
  263. goto cleanup;
  264. }
  265. ournames = validate_and_copy_tuple(names);
  266. if (ournames == NULL)
  267. goto cleanup;
  268. ourvarnames = validate_and_copy_tuple(varnames);
  269. if (ourvarnames == NULL)
  270. goto cleanup;
  271. if (freevars)
  272. ourfreevars = validate_and_copy_tuple(freevars);
  273. else
  274. ourfreevars = PyTuple_New(0);
  275. if (ourfreevars == NULL)
  276. goto cleanup;
  277. if (cellvars)
  278. ourcellvars = validate_and_copy_tuple(cellvars);
  279. else
  280. ourcellvars = PyTuple_New(0);
  281. if (ourcellvars == NULL)
  282. goto cleanup;
  283. co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
  284. nlocals, stacksize, flags,
  285. code, consts, ournames, ourvarnames,
  286. ourfreevars, ourcellvars, filename,
  287. name, firstlineno, lnotab);
  288. cleanup:
  289. Py_XDECREF(ournames);
  290. Py_XDECREF(ourvarnames);
  291. Py_XDECREF(ourfreevars);
  292. Py_XDECREF(ourcellvars);
  293. return co;
  294. }
  295. static void
  296. code_dealloc(PyCodeObject *co)
  297. {
  298. Py_XDECREF(co->co_code);
  299. Py_XDECREF(co->co_consts);
  300. Py_XDECREF(co->co_names);
  301. Py_XDECREF(co->co_varnames);
  302. Py_XDECREF(co->co_freevars);
  303. Py_XDECREF(co->co_cellvars);
  304. Py_XDECREF(co->co_filename);
  305. Py_XDECREF(co->co_name);
  306. Py_XDECREF(co->co_lnotab);
  307. if (co->co_zombieframe != NULL)
  308. PyObject_GC_Del(co->co_zombieframe);
  309. if (co->co_weakreflist != NULL)
  310. PyObject_ClearWeakRefs((PyObject*)co);
  311. PyObject_DEL(co);
  312. }
  313. static PyObject *
  314. code_repr(PyCodeObject *co)
  315. {
  316. int lineno;
  317. if (co->co_firstlineno != 0)
  318. lineno = co->co_firstlineno;
  319. else
  320. lineno = -1;
  321. if (co->co_filename && PyUnicode_Check(co->co_filename)) {
  322. return PyUnicode_FromFormat(
  323. "<code object %U at %p, file \"%U\", line %d>",
  324. co->co_name, co, co->co_filename, lineno);
  325. } else {
  326. return PyUnicode_FromFormat(
  327. "<code object %U at %p, file ???, line %d>",
  328. co->co_name, co, lineno);
  329. }
  330. }
  331. static PyObject *
  332. code_richcompare(PyObject *self, PyObject *other, int op)
  333. {
  334. PyCodeObject *co, *cp;
  335. int eq;
  336. PyObject *res;
  337. if ((op != Py_EQ && op != Py_NE) ||
  338. !PyCode_Check(self) ||
  339. !PyCode_Check(other)) {
  340. Py_INCREF(Py_NotImplemented);
  341. return Py_NotImplemented;
  342. }
  343. co = (PyCodeObject *)self;
  344. cp = (PyCodeObject *)other;
  345. eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
  346. if (eq <= 0) goto unequal;
  347. eq = co->co_argcount == cp->co_argcount;
  348. if (!eq) goto unequal;
  349. eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
  350. if (!eq) goto unequal;
  351. eq = co->co_nlocals == cp->co_nlocals;
  352. if (!eq) goto unequal;
  353. eq = co->co_flags == cp->co_flags;
  354. if (!eq) goto unequal;
  355. eq = co->co_firstlineno == cp->co_firstlineno;
  356. if (!eq) goto unequal;
  357. eq = PyObject_RichCompareBool(co->co_code, cp->co_code, Py_EQ);
  358. if (eq <= 0) goto unequal;
  359. eq = PyObject_RichCompareBool(co->co_consts, cp->co_consts, Py_EQ);
  360. if (eq <= 0) goto unequal;
  361. eq = PyObject_RichCompareBool(co->co_names, cp->co_names, Py_EQ);
  362. if (eq <= 0) goto unequal;
  363. eq = PyObject_RichCompareBool(co->co_varnames, cp->co_varnames, Py_EQ);
  364. if (eq <= 0) goto unequal;
  365. eq = PyObject_RichCompareBool(co->co_freevars, cp->co_freevars, Py_EQ);
  366. if (eq <= 0) goto unequal;
  367. eq = PyObject_RichCompareBool(co->co_cellvars, cp->co_cellvars, Py_EQ);
  368. if (eq <= 0) goto unequal;
  369. if (op == Py_EQ)
  370. res = Py_True;
  371. else
  372. res = Py_False;
  373. goto done;
  374. unequal:
  375. if (eq < 0)
  376. return NULL;
  377. if (op == Py_NE)
  378. res = Py_True;
  379. else
  380. res = Py_False;
  381. done:
  382. Py_INCREF(res);
  383. return res;
  384. }
  385. static Py_hash_t
  386. code_hash(PyCodeObject *co)
  387. {
  388. Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
  389. h0 = PyObject_Hash(co->co_name);
  390. if (h0 == -1) return -1;
  391. h1 = PyObject_Hash(co->co_code);
  392. if (h1 == -1) return -1;
  393. h2 = PyObject_Hash(co->co_consts);
  394. if (h2 == -1) return -1;
  395. h3 = PyObject_Hash(co->co_names);
  396. if (h3 == -1) return -1;
  397. h4 = PyObject_Hash(co->co_varnames);
  398. if (h4 == -1) return -1;
  399. h5 = PyObject_Hash(co->co_freevars);
  400. if (h5 == -1) return -1;
  401. h6 = PyObject_Hash(co->co_cellvars);
  402. if (h6 == -1) return -1;
  403. h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
  404. co->co_argcount ^ co->co_kwonlyargcount ^
  405. co->co_nlocals ^ co->co_flags;
  406. if (h == -1) h = -2;
  407. return h;
  408. }
  409. /* XXX code objects need to participate in GC? */
  410. PyTypeObject PyCode_Type = {
  411. PyVarObject_HEAD_INIT(&PyType_Type, 0)
  412. "code",
  413. sizeof(PyCodeObject),
  414. 0,
  415. (destructor)code_dealloc, /* tp_dealloc */
  416. 0, /* tp_print */
  417. 0, /* tp_getattr */
  418. 0, /* tp_setattr */
  419. 0, /* tp_reserved */
  420. (reprfunc)code_repr, /* tp_repr */
  421. 0, /* tp_as_number */
  422. 0, /* tp_as_sequence */
  423. 0, /* tp_as_mapping */
  424. (hashfunc)code_hash, /* tp_hash */
  425. 0, /* tp_call */
  426. 0, /* tp_str */
  427. PyObject_GenericGetAttr, /* tp_getattro */
  428. 0, /* tp_setattro */
  429. 0, /* tp_as_buffer */
  430. Py_TPFLAGS_DEFAULT, /* tp_flags */
  431. code_doc, /* tp_doc */
  432. 0, /* tp_traverse */
  433. 0, /* tp_clear */
  434. code_richcompare, /* tp_richcompare */
  435. offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
  436. 0, /* tp_iter */
  437. 0, /* tp_iternext */
  438. 0, /* tp_methods */
  439. code_memberlist, /* tp_members */
  440. 0, /* tp_getset */
  441. 0, /* tp_base */
  442. 0, /* tp_dict */
  443. 0, /* tp_descr_get */
  444. 0, /* tp_descr_set */
  445. 0, /* tp_dictoffset */
  446. 0, /* tp_init */
  447. 0, /* tp_alloc */
  448. code_new, /* tp_new */
  449. };
  450. /* Use co_lnotab to compute the line number from a bytecode index, addrq. See
  451. lnotab_notes.txt for the details of the lnotab representation.
  452. */
  453. int
  454. PyCode_Addr2Line(PyCodeObject *co, int addrq)
  455. {
  456. Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
  457. unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
  458. int line = co->co_firstlineno;
  459. int addr = 0;
  460. while (--size >= 0) {
  461. addr += *p++;
  462. if (addr > addrq)
  463. break;
  464. line += *p++;
  465. }
  466. return line;
  467. }
  468. /* Update *bounds to describe the first and one-past-the-last instructions in
  469. the same line as lasti. Return the number of that line. */
  470. int
  471. _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
  472. {
  473. Py_ssize_t size;
  474. int addr, line;
  475. unsigned char* p;
  476. p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
  477. size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
  478. addr = 0;
  479. line = co->co_firstlineno;
  480. assert(line > 0);
  481. /* possible optimization: if f->f_lasti == instr_ub
  482. (likely to be a common case) then we already know
  483. instr_lb -- if we stored the matching value of p
  484. somwhere we could skip the first while loop. */
  485. /* See lnotab_notes.txt for the description of
  486. co_lnotab. A point to remember: increments to p
  487. come in (addr, line) pairs. */
  488. bounds->ap_lower = 0;
  489. while (size > 0) {
  490. if (addr + *p > lasti)
  491. break;
  492. addr += *p++;
  493. if (*p)
  494. bounds->ap_lower = addr;
  495. line += *p++;
  496. --size;
  497. }
  498. if (size > 0) {
  499. while (--size >= 0) {
  500. addr += *p++;
  501. if (*p++)
  502. break;
  503. }
  504. bounds->ap_upper = addr;
  505. }
  506. else {
  507. bounds->ap_upper = INT_MAX;
  508. }
  509. return line;
  510. }