summaryrefslogtreecommitdiffstats
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c156
1 files changed, 66 insertions, 90 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index 9879df5..bb938ea 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -8,7 +8,7 @@
/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
static int
-all_name_chars(unsigned char *s)
+all_name_chars(Py_UNICODE *s)
{
static char ok_name_char[256];
static unsigned char *name_chars = (unsigned char *)NAME_CHARS;
@@ -19,6 +19,8 @@ all_name_chars(unsigned char *s)
ok_name_char[*p] = 1;
}
while (*s) {
+ if (*s >= 128)
+ return 0;
if (ok_name_char[*s++] == 0)
return 0;
}
@@ -32,16 +34,17 @@ intern_strings(PyObject *tuple)
for (i = PyTuple_GET_SIZE(tuple); --i >= 0; ) {
PyObject *v = PyTuple_GET_ITEM(tuple, i);
- if (v == NULL || !PyString_CheckExact(v)) {
+ if (v == NULL || !PyUnicode_CheckExact(v)) {
Py_FatalError("non-string found in code slot");
}
- PyString_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
+ PyUnicode_InternInPlace(&PyTuple_GET_ITEM(tuple, i));
}
}
PyCodeObject *
-PyCode_New(int argcount, int nlocals, int stacksize, int flags,
+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,
@@ -49,17 +52,18 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
{
PyCodeObject *co;
Py_ssize_t i;
+
/* Check argument types */
- if (argcount < 0 || nlocals < 0 ||
+ if (argcount < 0 || kwonlyargcount < 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 || !PyString_Check(name) ||
- filename == NULL || !PyString_Check(filename) ||
- lnotab == NULL || !PyString_Check(lnotab) ||
+ name == NULL || !PyUnicode_Check(name) ||
+ filename == NULL || !PyUnicode_Check(filename) ||
+ lnotab == NULL || !PyBytes_Check(lnotab) ||
!PyObject_CheckReadBuffer(code)) {
PyErr_BadInternalCall();
return NULL;
@@ -71,15 +75,16 @@ PyCode_New(int argcount, int nlocals, int stacksize, int flags,
/* Intern selected string constants */
for (i = PyTuple_Size(consts); --i >= 0; ) {
PyObject *v = PyTuple_GetItem(consts, i);
- if (!PyString_Check(v))
+ if (!PyUnicode_Check(v))
continue;
- if (!all_name_chars((unsigned char *)PyString_AS_STRING(v)))
+ if (!all_name_chars(PyUnicode_AS_UNICODE(v)))
continue;
- PyString_InternInPlace(&PyTuple_GET_ITEM(consts, i));
+ PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i));
}
co = PyObject_NEW(PyCodeObject, &PyCode_Type);
if (co != NULL) {
co->co_argcount = argcount;
+ co->co_kwonlyargcount = kwonlyargcount;
co->co_nlocals = nlocals;
co->co_stacksize = stacksize;
co->co_flags = flags;
@@ -117,7 +122,7 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
PyObject *funcname_ob = NULL;
PyCodeObject *result = NULL;
if (emptystring == NULL) {
- emptystring = PyString_FromString("");
+ emptystring = PyBytes_FromString("");
if (emptystring == NULL)
goto failed;
}
@@ -126,14 +131,15 @@ PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
if (nulltuple == NULL)
goto failed;
}
- funcname_ob = PyString_FromString(funcname);
+ funcname_ob = PyUnicode_FromString(funcname);
if (funcname_ob == NULL)
goto failed;
- filename_ob = PyString_FromString(filename);
+ filename_ob = PyUnicode_DecodeFSDefault(filename);
if (filename_ob == NULL)
goto failed;
result = PyCode_New(0, /* argcount */
+ 0, /* kwonlyargcount */
0, /* nlocals */
0, /* stacksize */
0, /* flags */
@@ -159,6 +165,7 @@ failed:
static PyMemberDef code_memberlist[] = {
{"co_argcount", T_INT, OFF(co_argcount), 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},
@@ -192,10 +199,10 @@ validate_and_copy_tuple(PyObject *tup)
for (i = 0; i < len; i++) {
item = PyTuple_GET_ITEM(tup, i);
- if (PyString_CheckExact(item)) {
+ if (PyUnicode_CheckExact(item)) {
Py_INCREF(item);
}
- else if (!PyString_Check(item)) {
+ else if (!PyUnicode_Check(item)) {
PyErr_Format(
PyExc_TypeError,
"name tuples must contain only "
@@ -205,9 +212,9 @@ validate_and_copy_tuple(PyObject *tup)
return NULL;
}
else {
- item = PyString_FromStringAndSize(
- PyString_AS_STRING(item),
- PyString_GET_SIZE(item));
+ item = PyUnicode_FromUnicode(
+ PyUnicode_AS_UNICODE(item),
+ PyUnicode_GET_SIZE(item));
if (item == NULL) {
Py_DECREF(newtuple);
return NULL;
@@ -220,8 +227,9 @@ validate_and_copy_tuple(PyObject *tup)
}
PyDoc_STRVAR(code_doc,
-"code(argcount, nlocals, stacksize, flags, codestring, constants, names,\n\
- varnames, filename, name, firstlineno, lnotab[, freevars[, cellvars]])\n\
+"code(argcount, kwonlyargcount, nlocals, stacksize, flags, codestring,\n\
+ constants, names, varnames, filename, name, firstlineno,\n\
+ lnotab[, freevars[, cellvars]])\n\
\n\
Create a code object. Not for the faint of heart.");
@@ -229,6 +237,7 @@ static PyObject *
code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
int argcount;
+ int kwonlyargcount;
int nlocals;
int stacksize;
int flags;
@@ -244,8 +253,9 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
int firstlineno;
PyObject *lnotab;
- if (!PyArg_ParseTuple(args, "iiiiSO!O!O!SSiS|O!O!:code",
- &argcount, &nlocals, &stacksize, &flags,
+ if (!PyArg_ParseTuple(args, "iiiiiSO!O!O!UUiS|O!O!:code",
+ &argcount, &kwonlyargcount,
+ &nlocals, &stacksize, &flags,
&code,
&PyTuple_Type, &consts,
&PyTuple_Type, &names,
@@ -263,6 +273,12 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
goto cleanup;
}
+ if (kwonlyargcount < 0) {
+ PyErr_SetString(
+ PyExc_ValueError,
+ "code: kwonlyargcount must not be negative");
+ goto cleanup;
+ }
if (nlocals < 0) {
PyErr_SetString(
PyExc_ValueError,
@@ -289,7 +305,8 @@ code_new(PyTypeObject *type, PyObject *args, PyObject *kw)
if (ourcellvars == NULL)
goto cleanup;
- co = (PyObject *)PyCode_New(argcount, nlocals, stacksize, flags,
+ co = (PyObject *)PyCode_New(argcount, kwonlyargcount,
+ nlocals, stacksize, flags,
code, consts, ournames, ourvarnames,
ourfreevars, ourcellvars, filename,
name, firstlineno, lnotab);
@@ -323,57 +340,20 @@ code_dealloc(PyCodeObject *co)
static PyObject *
code_repr(PyCodeObject *co)
{
- char buf[500];
- int lineno = -1;
- char *filename = "???";
- char *name = "???";
-
+ int lineno;
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 int
-code_compare(PyCodeObject *co, PyCodeObject *cp)
-{
- 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
- return 0;
+ 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);
+ }
}
static PyObject *
@@ -386,14 +366,6 @@ code_richcompare(PyObject *self, PyObject *other, int op)
if ((op != Py_EQ && op != Py_NE) ||
!PyCode_Check(self) ||
!PyCode_Check(other)) {
-
- /* 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;
}
@@ -405,6 +377,8 @@ code_richcompare(PyObject *self, PyObject *other, int op)
if (eq <= 0) goto unequal;
eq = co->co_argcount == cp->co_argcount;
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;
@@ -443,10 +417,10 @@ code_richcompare(PyObject *self, PyObject *other, int op)
return res;
}
-static long
+static Py_hash_t
code_hash(PyCodeObject *co)
{
- long h, h0, h1, h2, h3, h4, h5, h6;
+ Py_hash_t 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);
@@ -462,7 +436,8 @@ 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_nlocals ^ co->co_flags;
+ co->co_argcount ^ co->co_kwonlyargcount ^
+ co->co_nlocals ^ co->co_flags;
if (h == -1) h = -2;
return h;
}
@@ -478,7 +453,7 @@ PyTypeObject PyCode_Type = {
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
- (cmpfunc)code_compare, /* tp_compare */
+ 0, /* tp_reserved */
(reprfunc)code_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
@@ -494,7 +469,7 @@ 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 */
0, /* tp_methods */
@@ -517,8 +492,8 @@ PyTypeObject PyCode_Type = {
int
PyCode_Addr2Line(PyCodeObject *co, int addrq)
{
- int size = PyString_Size(co->co_lnotab) / 2;
- unsigned char *p = (unsigned char*)PyString_AsString(co->co_lnotab);
+ Py_ssize_t size = PyBytes_Size(co->co_lnotab) / 2;
+ unsigned char *p = (unsigned char*)PyBytes_AsString(co->co_lnotab);
int line = co->co_firstlineno;
int addr = 0;
while (--size >= 0) {
@@ -535,11 +510,12 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
int
_PyCode_CheckLineNumber(PyCodeObject* co, int lasti, PyAddrPair *bounds)
{
- int size, addr, line;
+ Py_ssize_t size;
+ int addr, line;
unsigned char* p;
- p = (unsigned char*)PyString_AS_STRING(co->co_lnotab);
- size = PyString_GET_SIZE(co->co_lnotab) / 2;
+ p = (unsigned char*)PyBytes_AS_STRING(co->co_lnotab);
+ size = PyBytes_GET_SIZE(co->co_lnotab) / 2;
addr = 0;
line = co->co_firstlineno;