summaryrefslogtreecommitdiffstats
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c688
1 files changed, 179 insertions, 509 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index f0b62ec..d50e4c6 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -1,38 +1,28 @@
-#include <stdbool.h>
-
#include "Python.h"
#include "code.h"
-#include "opcode.h"
#include "structmember.h"
-#include "pycore_code.h"
-#include "pycore_pystate.h"
-#include "pycore_tupleobject.h"
-#include "clinic/codeobject.c.h"
-
-/* Holder for co_extra information */
-typedef struct {
- Py_ssize_t ce_size;
- void *ce_extras[1];
-} _PyCodeObjectExtra;
-
-/*[clinic input]
-class code "PyCodeObject *" "&PyCode_Type"
-[clinic start generated code]*/
-/*[clinic end generated code: output=da39a3ee5e6b4b0d input=78aa5d576683bb4b]*/
-
-/* all_name_chars(s): true iff s matches [a-zA-Z0-9_]* */
+
+#define NAME_CHARS \
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz"
+
+/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
+
static int
all_name_chars(PyObject *o)
{
+ static char ok_name_char[256];
+ static const unsigned char *name_chars = (unsigned char *)NAME_CHARS;
const unsigned char *s, *e;
- if (!PyUnicode_IS_ASCII(o))
- return 0;
-
- s = PyUnicode_1BYTE_DATA(o);
- e = s + PyUnicode_GET_LENGTH(o);
- for (; s != e; s++) {
- if (!Py_ISALNUM(*s) && *s != '_')
+ if (ok_name_char[*name_chars] == 0) {
+ const unsigned char *p;
+ for (p = name_chars; *p; p++)
+ ok_name_char[*p] = 1;
+ }
+ s = (unsigned char *)PyString_AS_STRING(o);
+ e = s + PyString_GET_SIZE(o);
+ while (s != e) {
+ if (ok_name_char[*s++] == 0)
return 0;
}
return 1;
@@ -45,10 +35,10 @@ intern_strings(PyObject *tuple)
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
PyObject *v = PyTuple_GET_ITEM(tuple, i);
- if (v == NULL || !PyUnicode_CheckExact(v)) {
+ if (v == NULL || !PyString_CheckExact(v)) {
Py_FatalError("non-string found in code slot");
}
- PyUnicode_InternInPlace(&_PyTuple_ITEMS(tuple)[i]);
+ PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
}
}
@@ -61,14 +51,10 @@ intern_string_constants(PyObject *tuple)
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
PyObject *v = PyTuple_GET_ITEM(tuple, i);
- if (PyUnicode_CheckExact(v)) {
- if (PyUnicode_READY(v) == -1) {
- PyErr_Clear();
- continue;
- }
+ if (PyString_CheckExact(v)) {
if (all_name_chars(v)) {
PyObject *w = v;
- PyUnicode_InternInPlace(&v);
+ PyString_InternInPlace(&v);
if (w != v) {
PyTuple_SET_ITEM(tuple, i, v);
modified = 1;
@@ -102,204 +88,67 @@ intern_string_constants(PyObject *tuple)
return modified;
}
+
PyCodeObject *
-PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
- int nlocals, int stacksize, int flags,
- PyObject *code, PyObject *consts, PyObject *names,
- PyObject *varnames, PyObject *freevars, PyObject *cellvars,
- PyObject *filename, PyObject *name, int firstlineno,
- PyObject *lnotab)
+PyCode_New(int argcount, int nlocals, int stacksize, int flags,
+ PyObject *code, PyObject *consts, PyObject *names,
+ PyObject *varnames, PyObject *freevars, PyObject *cellvars,
+ PyObject *filename, PyObject *name, int firstlineno,
+ PyObject *lnotab)
{
PyCodeObject *co;
- Py_ssize_t *cell2arg = NULL;
- Py_ssize_t i, n_cellvars, n_varnames, total_args;
-
/* Check argument types */
- if (argcount < posonlyargcount || posonlyargcount < 0 ||
- kwonlyargcount < 0 || nlocals < 0 ||
- stacksize < 0 || flags < 0 ||
- code == NULL || !PyBytes_Check(code) ||
+ if (argcount < 0 || nlocals < 0 ||
+ code == NULL ||
consts == NULL || !PyTuple_Check(consts) ||
names == NULL || !PyTuple_Check(names) ||
varnames == NULL || !PyTuple_Check(varnames) ||
freevars == NULL || !PyTuple_Check(freevars) ||
cellvars == NULL || !PyTuple_Check(cellvars) ||
- name == NULL || !PyUnicode_Check(name) ||
- filename == NULL || !PyUnicode_Check(filename) ||
- lnotab == NULL || !PyBytes_Check(lnotab)) {
+ name == NULL || !PyString_Check(name) ||
+ filename == NULL || !PyString_Check(filename) ||
+ lnotab == NULL || !PyString_Check(lnotab) ||
+ !PyObject_CheckReadBuffer(code)) {
PyErr_BadInternalCall();
return NULL;
}
-
- /* Ensure that strings are ready Unicode string */
- if (PyUnicode_READY(name) < 0) {
- return NULL;
- }
- if (PyUnicode_READY(filename) < 0) {
- return NULL;
- }
-
intern_strings(names);
intern_strings(varnames);
intern_strings(freevars);
intern_strings(cellvars);
intern_string_constants(consts);
-
- /* Check for any inner or outer closure references */
- n_cellvars = PyTuple_GET_SIZE(cellvars);
- if (!n_cellvars && !PyTuple_GET_SIZE(freevars)) {
- flags |= CO_NOFREE;
- } else {
- flags &= ~CO_NOFREE;
- }
-
- n_varnames = PyTuple_GET_SIZE(varnames);
- if (argcount <= n_varnames && kwonlyargcount <= n_varnames) {
- /* Never overflows. */
- total_args = (Py_ssize_t)argcount + (Py_ssize_t)kwonlyargcount +
- ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0);
- }
- else {
- total_args = n_varnames + 1;
- }
- if (total_args > n_varnames) {
- PyErr_SetString(PyExc_ValueError, "code: varnames is too small");
- return NULL;
- }
-
- /* Create mapping between cells and arguments if needed. */
- if (n_cellvars) {
- bool used_cell2arg = false;
- cell2arg = PyMem_NEW(Py_ssize_t, n_cellvars);
- if (cell2arg == NULL) {
- PyErr_NoMemory();
- return NULL;
- }
- /* Find cells which are also arguments. */
- for (i = 0; i < n_cellvars; i++) {
- Py_ssize_t j;
- PyObject *cell = PyTuple_GET_ITEM(cellvars, i);
- cell2arg[i] = CO_CELL_NOT_AN_ARG;
- for (j = 0; j < total_args; j++) {
- PyObject *arg = PyTuple_GET_ITEM(varnames, j);
- int cmp = PyUnicode_Compare(cell, arg);
- if (cmp == -1 && PyErr_Occurred()) {
- PyMem_FREE(cell2arg);
- return NULL;
- }
- if (cmp == 0) {
- cell2arg[i] = j;
- used_cell2arg = true;
- break;
- }
- }
- }
- if (!used_cell2arg) {
- PyMem_FREE(cell2arg);
- cell2arg = NULL;
- }
- }
co = PyObject_NEW(PyCodeObject, &PyCode_Type);
- if (co == NULL) {
- if (cell2arg)
- PyMem_FREE(cell2arg);
- return NULL;
+ if (co != NULL) {
+ co->co_argcount = argcount;
+ co->co_nlocals = nlocals;
+ co->co_stacksize = stacksize;
+ co->co_flags = flags;
+ Py_INCREF(code);
+ co->co_code = code;
+ Py_INCREF(consts);
+ co->co_consts = consts;
+ Py_INCREF(names);
+ co->co_names = names;
+ Py_INCREF(varnames);
+ co->co_varnames = varnames;
+ Py_INCREF(freevars);
+ co->co_freevars = freevars;
+ Py_INCREF(cellvars);
+ co->co_cellvars = cellvars;
+ Py_INCREF(filename);
+ co->co_filename = filename;
+ Py_INCREF(name);
+ co->co_name = name;
+ co->co_firstlineno = firstlineno;
+ Py_INCREF(lnotab);
+ co->co_lnotab = lnotab;
+ co->co_zombieframe = NULL;
+ co->co_weakreflist = NULL;
}
- co->co_argcount = argcount;
- co->co_posonlyargcount = posonlyargcount;
- co->co_kwonlyargcount = kwonlyargcount;
- co->co_nlocals = nlocals;
- co->co_stacksize = stacksize;
- co->co_flags = flags;
- Py_INCREF(code);
- co->co_code = code;
- Py_INCREF(consts);
- co->co_consts = consts;
- Py_INCREF(names);
- co->co_names = names;
- Py_INCREF(varnames);
- co->co_varnames = varnames;
- Py_INCREF(freevars);
- co->co_freevars = freevars;
- Py_INCREF(cellvars);
- co->co_cellvars = cellvars;
- co->co_cell2arg = cell2arg;
- Py_INCREF(filename);
- co->co_filename = filename;
- Py_INCREF(name);
- co->co_name = name;
- co->co_firstlineno = firstlineno;
- Py_INCREF(lnotab);
- co->co_lnotab = lnotab;
- co->co_zombieframe = NULL;
- co->co_weakreflist = NULL;
- co->co_extra = NULL;
-
- co->co_opcache_map = NULL;
- co->co_opcache = NULL;
- co->co_opcache_flag = 0;
- co->co_opcache_size = 0;
return co;
}
PyCodeObject *
-PyCode_New(int argcount, int kwonlyargcount,
- int nlocals, int stacksize, int flags,
- PyObject *code, PyObject *consts, PyObject *names,
- PyObject *varnames, PyObject *freevars, PyObject *cellvars,
- PyObject *filename, PyObject *name, int firstlineno,
- PyObject *lnotab)
-{
- return PyCode_NewWithPosOnlyArgs(argcount, 0, kwonlyargcount, nlocals,
- stacksize, flags, code, consts, names,
- varnames, freevars, cellvars, filename,
- name, firstlineno, lnotab);
-}
-
-int
-_PyCode_InitOpcache(PyCodeObject *co)
-{
- Py_ssize_t co_size = PyBytes_Size(co->co_code) / sizeof(_Py_CODEUNIT);
- co->co_opcache_map = (unsigned char *)PyMem_Calloc(co_size, 1);
- if (co->co_opcache_map == NULL) {
- return -1;
- }
-
- _Py_CODEUNIT *opcodes = (_Py_CODEUNIT*)PyBytes_AS_STRING(co->co_code);
- Py_ssize_t opts = 0;
-
- for (Py_ssize_t i = 0; i < co_size;) {
- unsigned char opcode = _Py_OPCODE(opcodes[i]);
- i++; // 'i' is now aligned to (next_instr - first_instr)
-
- // TODO: LOAD_METHOD, LOAD_ATTR
- if (opcode == LOAD_GLOBAL) {
- opts++;
- co->co_opcache_map[i] = (unsigned char)opts;
- if (opts > 254) {
- break;
- }
- }
- }
-
- if (opts) {
- co->co_opcache = (_PyOpcache *)PyMem_Calloc(opts, sizeof(_PyOpcache));
- if (co->co_opcache == NULL) {
- PyMem_FREE(co->co_opcache_map);
- return -1;
- }
- }
- else {
- PyMem_FREE(co->co_opcache_map);
- co->co_opcache_map = NULL;
- co->co_opcache = NULL;
- }
-
- co->co_opcache_size = (unsigned char)opts;
- return 0;
-}
-
-PyCodeObject *
PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
{
static PyObject *emptystring = NULL;
@@ -308,7 +157,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
PyObject *funcname_ob = NULL;
PyCodeObject *result = NULL;
if (emptystring == NULL) {
- emptystring = PyBytes_FromString("");
+ emptystring = PyString_FromString("");
if (emptystring == NULL)
goto failed;
}
@@ -317,17 +166,14 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
if (nulltuple == NULL)
goto failed;
}
- funcname_ob = PyUnicode_FromString(funcname);
+ funcname_ob = PyString_FromString(funcname);
if (funcname_ob == NULL)
goto failed;
- filename_ob = PyUnicode_DecodeFSDefault(filename);
+ filename_ob = PyString_FromString(filename);
if (filename_ob == NULL)
goto failed;
- result = PyCode_NewWithPosOnlyArgs(
- 0, /* argcount */
- 0, /* posonlyargcount */
- 0, /* kwonlyargcount */
+ result = PyCode_New(0, /* argcount */
0, /* nlocals */
0, /* stacksize */
0, /* flags */
@@ -352,22 +198,20 @@ failed:
#define OFF(x) offsetof(PyCodeObject, x)
static PyMemberDef code_memberlist[] = {
- {"co_argcount", T_INT, OFF(co_argcount), READONLY},
- {"co_posonlyargcount", T_INT, OFF(co_posonlyargcount), READONLY},
- {"co_kwonlyargcount", T_INT, OFF(co_kwonlyargcount), READONLY},
- {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
- {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
- {"co_flags", T_INT, OFF(co_flags), READONLY},
- {"co_code", T_OBJECT, OFF(co_code), READONLY},
- {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
- {"co_names", T_OBJECT, OFF(co_names), READONLY},
- {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
- {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
- {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
- {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
- {"co_name", T_OBJECT, OFF(co_name), READONLY},
- {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
- {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
+ {"co_argcount", T_INT, OFF(co_argcount), READONLY},
+ {"co_nlocals", T_INT, OFF(co_nlocals), READONLY},
+ {"co_stacksize",T_INT, OFF(co_stacksize), READONLY},
+ {"co_flags", T_INT, OFF(co_flags), READONLY},
+ {"co_code", T_OBJECT, OFF(co_code), READONLY},
+ {"co_consts", T_OBJECT, OFF(co_consts), READONLY},
+ {"co_names", T_OBJECT, OFF(co_names), READONLY},
+ {"co_varnames", T_OBJECT, OFF(co_varnames), READONLY},
+ {"co_freevars", T_OBJECT, OFF(co_freevars), READONLY},
+ {"co_cellvars", T_OBJECT, OFF(co_cellvars), READONLY},
+ {"co_filename", T_OBJECT, OFF(co_filename), READONLY},
+ {"co_name", T_OBJECT, OFF(co_name), READONLY},
+ {"co_firstlineno", T_INT, OFF(co_firstlineno), READONLY},
+ {"co_lnotab", T_OBJECT, OFF(co_lnotab), READONLY},
{NULL} /* Sentinel */
};
@@ -388,10 +232,10 @@ validate_and_copy_tuple(PyObject *tup)
for (i = 0; i < len; i++) {
item = PyTuple_GET_ITEM(tup, i);
- if (PyUnicode_CheckExact(item)) {
+ if (PyString_CheckExact(item)) {
Py_INCREF(item);
}
- else if (!PyUnicode_Check(item)) {
+ else if (!PyString_Check(item)) {
PyErr_Format(
PyExc_TypeError,
"name tuples must contain only "
@@ -401,7 +245,9 @@ validate_and_copy_tuple(PyObject *tup)
return NULL;
}
else {
- item = _PyUnicode_Copy(item);
+ item = PyString_FromStringAndSize(
+ PyString_AS_STRING(item),
+ PyString_GET_SIZE(item));
if (item == NULL) {
Py_DECREF(newtuple);
return NULL;
@@ -414,9 +260,8 @@ validate_and_copy_tuple(PyObject *tup)
}
PyDoc_STRVAR(code_doc,
-"code(argcount, posonlyargcount, kwonlyargcount, nlocals, stacksize,\n\
- flags, codestring, constants, names, varnames, filename, name,\n\
- firstlineno, lnotab[, freevars[, cellvars]])\n\
+"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
+ varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
\n\
Create a code object. Not for the faint of heart.");
@@ -424,8 +269,6 @@ static PyObject *
code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
int argcount;
- int posonlyargcount;
- int kwonlyargcount;
int nlocals;
int stacksize;
int flags;
@@ -441,9 +284,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
int firstlineno;
PyObject *lnotab;
- if (!PyArg_ParseTuple(args, "iiiiiiSO!O!O!UUiS|O!O!:code",
- &argcount, &posonlyargcount, &kwonlyargcount,
- &nlocals, &stacksize, &flags,
+ if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
+ &argcount, &nlocals, &stacksize, &flags,
&code,
&PyTuple_Type, &consts,
&PyTuple_Type, &names,
@@ -454,12 +296,6 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
&PyTuple_Type, &cellvars))
return NULL;
- if (PySys_Audit("code.__new__", "OOOiiiiii",
- code, filename, name, argcount, posonlyargcount,
- kwonlyargcount, nlocals, stacksize, flags) < 0) {
- goto cleanup;
- }
-
if (argcount < 0) {
PyErr_SetString(
PyExc_ValueError,
@@ -467,19 +303,6 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
goto cleanup;
}
- if (posonlyargcount < 0) {
- PyErr_SetString(
- PyExc_ValueError,
- "code: posonlyargcount must not be negative");
- goto cleanup;
- }
-
- if (kwonlyargcount < 0) {
- PyErr_SetString(
- PyExc_ValueError,
- "code: kwonlyargcount must not be negative");
- goto cleanup;
- }
if (nlocals < 0) {
PyErr_SetString(
PyExc_ValueError,
@@ -506,14 +329,11 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (ourcellvars == NULL)
goto cleanup;
- co = (PyObject *)PyCode_NewWithPosOnlyArgs(argcount, posonlyargcount,
- kwonlyargcount,
- nlocals, stacksize, flags,
- code, consts, ournames,
- ourvarnames, ourfreevars,
- ourcellvars, filename,
- name, firstlineno, lnotab);
- cleanup:
+ co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
+ code, consts, ournames, ourvarnames,
+ ourfreevars, ourcellvars, filename,
+ name, firstlineno, lnotab);
+ cleanup:
Py_XDECREF(ournames);
Py_XDECREF(ourvarnames);
Py_XDECREF(ourfreevars);
@@ -524,30 +344,6 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
static void
code_dealloc(PyCodeObject *co)
{
- if (co->co_opcache != NULL) {
- PyMem_FREE(co->co_opcache);
- }
- if (co->co_opcache_map != NULL) {
- PyMem_FREE(co->co_opcache_map);
- }
- co->co_opcache_flag = 0;
- co->co_opcache_size = 0;
-
- if (co->co_extra != NULL) {
- PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
- _PyCodeObjectExtra *co_extra = co->co_extra;
-
- for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
- freefunc free_extra = interp->co_extra_freefuncs[i];
-
- if (free_extra != NULL) {
- free_extra(co_extra->ce_extras[i]);
- }
- }
-
- PyMem_Free(co_extra);
- }
-
Py_XDECREF(co->co_code);
Py_XDECREF(co->co_consts);
Py_XDECREF(co->co_names);
@@ -557,8 +353,6 @@ code_dealloc(PyCodeObject *co)
Py_XDECREF(co->co_filename);
Py_XDECREF(co->co_name);
Py_XDECREF(co->co_lnotab);
- if (co->co_cell2arg != NULL)
- PyMem_FREE(co->co_cell2arg);
if (co->co_zombieframe != NULL)
PyObject_GC_Del(co->co_zombieframe);
if (co->co_weakreflist != NULL)
@@ -567,111 +361,59 @@ code_dealloc(PyCodeObject *co)
}
static PyObject *
-code_sizeof(PyCodeObject *co, PyObject *Py_UNUSED(args))
-{
- Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co));
- _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
-
- if (co->co_cell2arg != NULL && co->co_cellvars != NULL) {
- res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(Py_ssize_t);
- }
- if (co_extra != NULL) {
- res += sizeof(_PyCodeObjectExtra) +
- (co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]);
- }
- if (co->co_opcache != NULL) {
- assert(co->co_opcache_map != NULL);
- // co_opcache_map
- res += PyBytes_GET_SIZE(co->co_code) / sizeof(_Py_CODEUNIT);
- // co_opcache
- res += co->co_opcache_size * sizeof(_PyOpcache);
- }
- return PyLong_FromSsize_t(res);
-}
-
-/*[clinic input]
-code.replace
-
- *
- co_argcount: int(c_default="self->co_argcount") = -1
- co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
- co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
- co_nlocals: int(c_default="self->co_nlocals") = -1
- co_stacksize: int(c_default="self->co_stacksize") = -1
- co_flags: int(c_default="self->co_flags") = -1
- co_firstlineno: int(c_default="self->co_firstlineno") = -1
- co_code: PyBytesObject(c_default="(PyBytesObject *)self->co_code") = None
- co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
- co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None
- co_varnames: object(subclass_of="&PyTuple_Type", c_default="self->co_varnames") = None
- co_freevars: object(subclass_of="&PyTuple_Type", c_default="self->co_freevars") = None
- co_cellvars: object(subclass_of="&PyTuple_Type", c_default="self->co_cellvars") = None
- co_filename: unicode(c_default="self->co_filename") = None
- co_name: unicode(c_default="self->co_name") = None
- co_lnotab: PyBytesObject(c_default="(PyBytesObject *)self->co_lnotab") = None
-
-Return a new code object with new specified fields.
-[clinic start generated code]*/
-
-static PyObject *
-code_replace_impl(PyCodeObject *self, int co_argcount,
- int co_posonlyargcount, int co_kwonlyargcount,
- int co_nlocals, int co_stacksize, int co_flags,
- int co_firstlineno, PyBytesObject *co_code,
- PyObject *co_consts, PyObject *co_names,
- PyObject *co_varnames, PyObject *co_freevars,
- PyObject *co_cellvars, PyObject *co_filename,
- PyObject *co_name, PyBytesObject *co_lnotab)
-/*[clinic end generated code: output=25c8e303913bcace input=77189e46579ec426]*/
+code_repr(PyCodeObject *co)
{
-#define CHECK_INT_ARG(ARG) \
- if (ARG < 0) { \
- PyErr_SetString(PyExc_ValueError, \
- #ARG " must be a positive integer"); \
- return NULL; \
- }
-
- CHECK_INT_ARG(co_argcount);
- CHECK_INT_ARG(co_posonlyargcount);
- CHECK_INT_ARG(co_kwonlyargcount);
- CHECK_INT_ARG(co_nlocals);
- CHECK_INT_ARG(co_stacksize);
- CHECK_INT_ARG(co_flags);
- CHECK_INT_ARG(co_firstlineno);
-
-#undef CHECK_INT_ARG
-
- if (PySys_Audit("code.__new__", "OOOiiiiii",
- co_code, co_filename, co_name, co_argcount,
- co_posonlyargcount, co_kwonlyargcount, co_nlocals,
- co_stacksize, co_flags) < 0) {
- return NULL;
- }
+ char buf[500];
+ int lineno = -1;
+ char *filename = "???";
+ char *name = "???";
- return (PyObject *)PyCode_NewWithPosOnlyArgs(
- co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
- co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
- co_varnames, co_freevars, co_cellvars, co_filename, co_name,
- co_firstlineno, (PyObject*)co_lnotab);
+ if (co->co_firstlineno != 0)
+ lineno = co->co_firstlineno;
+ if (co->co_filename && PyString_Check(co->co_filename))
+ filename = PyString_AS_STRING(co->co_filename);
+ if (co->co_name && PyString_Check(co->co_name))
+ name = PyString_AS_STRING(co->co_name);
+ PyOS_snprintf(buf, sizeof(buf),
+ "<code object %.100s at %p, file \"%.300s\", line %d>",
+ name, co, filename, lineno);
+ return PyString_FromString(buf);
}
-static PyObject *
-code_repr(PyCodeObject *co)
+static int
+code_compare(PyCodeObject *co, PyCodeObject *cp)
{
- int lineno;
- if (co->co_firstlineno != 0)
- lineno = co->co_firstlineno;
+ int cmp;
+ cmp = PyObject_Compare(co->co_name, cp->co_name);
+ if (cmp) return cmp;
+ cmp = co->co_argcount - cp->co_argcount;
+ if (cmp) goto normalize;
+ cmp = co->co_nlocals - cp->co_nlocals;
+ if (cmp) goto normalize;
+ cmp = co->co_flags - cp->co_flags;
+ if (cmp) goto normalize;
+ cmp = co->co_firstlineno - cp->co_firstlineno;
+ if (cmp) goto normalize;
+ cmp = PyObject_Compare(co->co_code, cp->co_code);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_consts, cp->co_consts);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_names, cp->co_names);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_varnames, cp->co_varnames);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_freevars, cp->co_freevars);
+ if (cmp) return cmp;
+ cmp = PyObject_Compare(co->co_cellvars, cp->co_cellvars);
+ return cmp;
+
+ normalize:
+ if (cmp > 0)
+ return 1;
+ else if (cmp < 0)
+ return -1;
else
- lineno = -1;
- if (co->co_filename && PyUnicode_Check(co->co_filename)) {
- return PyUnicode_FromFormat(
- "<code object %U at %p, file \"%U\", line %d>",
- co->co_name, co, co->co_filename, lineno);
- } else {
- return PyUnicode_FromFormat(
- "<code object %U at %p, file ???, line %d>",
- co->co_name, co, lineno);
- }
+ return 0;
}
PyObject*
@@ -679,21 +421,16 @@ _PyCode_ConstantKey(PyObject *op)
{
PyObject *key;
- /* Py_None and Py_Ellipsis are singletons. */
- if (op == Py_None || op == Py_Ellipsis
- || PyLong_CheckExact(op)
+ /* Py_None is a singleton */
+ if (op == Py_None
+ || _PyAnyInt_CheckExact(op)
+ || PyBool_Check(op)
+ || PyBytes_CheckExact(op)
+#ifdef Py_USING_UNICODE
|| PyUnicode_CheckExact(op)
+#endif
/* code_richcompare() uses _PyCode_ConstantKey() internally */
- || PyCode_Check(op))
- {
- /* Objects of these types are always different from object of other
- * type and from tuples. */
- Py_INCREF(op);
- key = op;
- }
- else if (PyBool_Check(op) || PyBytes_CheckExact(op)) {
- /* Make booleans different from integers 0 and 1.
- * Avoid BytesWarning from comparing bytes with strings. */
+ || PyCode_Check(op)) {
key = PyTuple_Pack(2, Py_TYPE(op), op);
}
else if (PyFloat_CheckExact(op)) {
@@ -706,6 +443,7 @@ _PyCode_ConstantKey(PyObject *op)
else
key = PyTuple_Pack(2, Py_TYPE(op), op);
}
+#ifndef WITHOUT_COMPLEX
else if (PyComplex_CheckExact(op)) {
Py_complex z;
int real_negzero, imag_negzero;
@@ -731,6 +469,7 @@ _PyCode_ConstantKey(PyObject *op)
key = PyTuple_Pack(2, Py_TYPE(op), op);
}
}
+#endif
else if (PyTuple_CheckExact(op)) {
Py_ssize_t i, len;
PyObject *tuple;
@@ -753,13 +492,13 @@ _PyCode_ConstantKey(PyObject *op)
PyTuple_SET_ITEM(tuple, i, item_key);
}
- key = PyTuple_Pack(2, tuple, op);
+ key = PyTuple_Pack(3, Py_TYPE(op), op, tuple);
Py_DECREF(tuple);
}
else if (PyFrozenSet_CheckExact(op)) {
Py_ssize_t pos = 0;
PyObject *item;
- Py_hash_t hash;
+ long hash;
Py_ssize_t i, len;
PyObject *tuple, *set;
@@ -787,7 +526,7 @@ _PyCode_ConstantKey(PyObject *op)
if (set == NULL)
return NULL;
- key = PyTuple_Pack(2, set, op);
+ key = PyTuple_Pack(3, Py_TYPE(op), op, set);
Py_DECREF(set);
return key;
}
@@ -798,7 +537,7 @@ _PyCode_ConstantKey(PyObject *op)
if (obj_id == NULL)
return NULL;
- key = PyTuple_Pack(2, obj_id, op);
+ key = PyTuple_Pack(3, Py_TYPE(op), op, obj_id);
Py_DECREF(obj_id);
}
return key;
@@ -815,20 +554,25 @@ code_richcompare(PyObject *self, PyObject *other, int op)
if ((op != Py_EQ && op != Py_NE) ||
!PyCode_Check(self) ||
!PyCode_Check(other)) {
- Py_RETURN_NOTIMPLEMENTED;
+
+ /* Py3K warning if types are not equal and comparison
+ isn't == or != */
+ if (PyErr_WarnPy3k("code inequality comparisons not supported "
+ "in 3.x", 1) < 0) {
+ return NULL;
+ }
+
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
}
co = (PyCodeObject *)self;
cp = (PyCodeObject *)other;
eq = PyObject_RichCompareBool(co->co_name, cp->co_name, Py_EQ);
- if (!eq) goto unequal;
+ if (eq <= 0) goto unequal;
eq = co->co_argcount == cp->co_argcount;
if (!eq) goto unequal;
- eq = co->co_posonlyargcount == cp->co_posonlyargcount;
- if (!eq) goto unequal;
- eq = co->co_kwonlyargcount == cp->co_kwonlyargcount;
- if (!eq) goto unequal;
eq = co->co_nlocals == cp->co_nlocals;
if (!eq) goto unequal;
eq = co->co_flags == cp->co_flags;
@@ -880,10 +624,10 @@ code_richcompare(PyObject *self, PyObject *other, int op)
return res;
}
-static Py_hash_t
+static long
code_hash(PyCodeObject *co)
{
- Py_hash_t h, h0, h1, h2, h3, h4, h5, h6;
+ long h, h0, h1, h2, h3, h4, h5, h6;
h0 = PyObject_Hash(co->co_name);
if (h0 == -1) return -1;
h1 = PyObject_Hash(co->co_code);
@@ -899,30 +643,23 @@ code_hash(PyCodeObject *co)
h6 = PyObject_Hash(co->co_cellvars);
if (h6 == -1) return -1;
h = h0 ^ h1 ^ h2 ^ h3 ^ h4 ^ h5 ^ h6 ^
- co->co_argcount ^ co->co_posonlyargcount ^ co->co_kwonlyargcount ^
- co->co_nlocals ^ co->co_flags;
+ co->co_argcount ^ co->co_nlocals ^ co->co_flags;
if (h == -1) h = -2;
return h;
}
/* XXX code objects need to participate in GC? */
-static struct PyMethodDef code_methods[] = {
- {"__sizeof__", (PyCFunction)code_sizeof, METH_NOARGS},
- CODE_REPLACE_METHODDEF
- {NULL, NULL} /* sentinel */
-};
-
PyTypeObject PyCode_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"code",
sizeof(PyCodeObject),
0,
(destructor)code_dealloc, /* tp_dealloc */
- 0, /* tp_vectorcall_offset */
+ 0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- 0, /* tp_as_async */
+ (cmpfunc)code_compare, /* tp_compare */
(reprfunc)code_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -938,10 +675,10 @@ PyTypeObject PyCode_Type = {
0, /* tp_traverse */
0, /* tp_clear */
code_richcompare, /* tp_richcompare */
- offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
+ offsetof(PyCodeObject, co_weakreflist), /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
- code_methods, /* tp_methods */
+ 0, /* tp_methods */
code_memberlist, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
@@ -961,16 +698,15 @@ PyTypeObject PyCode_Type = {
int
PyCode_Addr2Line(PyCodeObject *co, int addrq)
{
- Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
- unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
+ int size = PyString_Size(co->co_lnotab) / 2;
+ unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
int line = co->co_firstlineno;
int addr = 0;
while (--size >= 0) {
addr += *p++;
if (addr > addrq)
break;
- line += (signed char)*p;
- p++;
+ line += *p++;
}
return line;
}
@@ -980,12 +716,11 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
int
_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
{
- Py_ssize_t size;
- int addr, line;
+ int size, addr, line;
unsigned char* p;
- p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
- size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
+ p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
+ size = PyString_GET_SIZE(co->co_lnotab) / 2;
addr = 0;
line = co->co_firstlineno;
@@ -1005,19 +740,17 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
if (addr + *p > lasti)
break;
addr += *p++;
- if ((signed char)*p)
+ if (*p)
bounds->ap_lower = addr;
- line += (signed char)*p;
- p++;
+ line += *p++;
--size;
}
if (size > 0) {
while (--size >= 0) {
addr += *p++;
- if ((signed char)*p)
+ if (*p++)
break;
- p++;
}
bounds->ap_upper = addr;
}
@@ -1027,66 +760,3 @@ _PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
return line;
}
-
-
-int
-_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
-{
- if (!PyCode_Check(code)) {
- PyErr_BadInternalCall();
- return -1;
- }
-
- PyCodeObject *o = (PyCodeObject*) code;
- _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) o->co_extra;
-
- if (co_extra == NULL || co_extra->ce_size <= index) {
- *extra = NULL;
- return 0;
- }
-
- *extra = co_extra->ce_extras[index];
- return 0;
-}
-
-
-int
-_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
-{
- PyInterpreterState *interp = _PyInterpreterState_GET_UNSAFE();
-
- if (!PyCode_Check(code) || index < 0 ||
- index >= interp->co_extra_user_count) {
- PyErr_BadInternalCall();
- return -1;
- }
-
- PyCodeObject *o = (PyCodeObject*) code;
- _PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
-
- if (co_extra == NULL || co_extra->ce_size <= index) {
- Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size);
- co_extra = PyMem_Realloc(
- co_extra,
- sizeof(_PyCodeObjectExtra) +
- (interp->co_extra_user_count-1) * sizeof(void*));
- if (co_extra == NULL) {
- return -1;
- }
- for (; i < interp->co_extra_user_count; i++) {
- co_extra->ce_extras[i] = NULL;
- }
- co_extra->ce_size = interp->co_extra_user_count;
- o->co_extra = co_extra;
- }
-
- if (co_extra->ce_extras[index] != NULL) {
- freefunc free = interp->co_extra_freefuncs[index];
- if (free != NULL) {
- free(co_extra->ce_extras[index]);
- }
- }
-
- co_extra->ce_extras[index] = extra;
- return 0;
-}