From 78e7d230757093d24166ed820271a07ddf77d3e3 Mon Sep 17 00:00:00 2001 From: Benjamin Peterson Date: Sat, 25 Jun 2011 22:54:45 -0500 Subject: map cells to arg slots at code creation time (closes #12399) This removes nested loops in PyEval_EvalCodeEx. --- Objects/codeobject.c | 94 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 65 insertions(+), 29 deletions(-) (limited to 'Objects/codeobject.c') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index bb938ea0aa..db5c17ecb8 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -51,7 +51,8 @@ PyCode_New(int argcount, int kwonlyargcount, PyObject *lnotab) { PyCodeObject *co; - Py_ssize_t i; + unsigned char *cell2arg = NULL; + Py_ssize_t i, n_cellvars; /* Check argument types */ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || @@ -68,12 +69,13 @@ PyCode_New(int argcount, int kwonlyargcount, PyErr_BadInternalCall(); return NULL; } + n_cellvars = PyTuple_GET_SIZE(cellvars); intern_strings(names); intern_strings(varnames); intern_strings(freevars); intern_strings(cellvars); /* Intern selected string constants */ - for (i = PyTuple_Size(consts); --i >= 0; ) { + for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { PyObject *v = PyTuple_GetItem(consts, i); if (!PyUnicode_Check(v)) continue; @@ -81,35 +83,67 @@ PyCode_New(int argcount, int kwonlyargcount, continue; PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); } + /* Create mapping between cells and arguments if needed. */ + if (n_cellvars) { + Py_ssize_t total_args = argcount + kwonlyargcount + + ((flags & CO_VARARGS) != 0) + ((flags & CO_VARKEYWORDS) != 0); + Py_ssize_t alloc_size = sizeof(unsigned char) * n_cellvars; + int used_cell2arg = 0; + cell2arg = PyMem_MALLOC(alloc_size); + if (cell2arg == NULL) + return NULL; + memset(cell2arg, CO_CELL_NOT_AN_ARG, alloc_size); + /* Find cells which are also arguments. */ + for (i = 0; i < n_cellvars; i++) { + Py_ssize_t j; + PyObject *cell = PyTuple_GET_ITEM(cellvars, i); + for (j = 0; j < total_args; j++) { + PyObject *arg = PyTuple_GET_ITEM(varnames, j); + if (!PyUnicode_Compare(cell, arg)) { + cell2arg[i] = j; + used_cell2arg = 1; + break; + } + } + } + if (!used_cell2arg) { + PyMem_FREE(cell2arg); + cell2arg = NULL; + } + } 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; - 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; + if (co == NULL) { + if (cell2arg) + PyMem_FREE(cell2arg); + return NULL; } + co->co_argcount = argcount; + 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; return co; } @@ -330,6 +364,8 @@ 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) -- cgit v1.2.1 From 174958263e0e4854bb560dd8609a76e797cc66f7 Mon Sep 17 00:00:00 2001 From: Brian Curtin Date: Wed, 10 Aug 2011 20:28:54 -0500 Subject: Replace Py_NotImplemented returns with the macro form Py_RETURN_NOTIMPLEMENTED. The macro was introduced in #12724. --- Objects/codeobject.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'Objects/codeobject.c') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index db5c17ecb8..3f77718f2c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -402,8 +402,7 @@ code_richcompare(PyObject *self, PyObject *other, int op) if ((op != Py_EQ && op != Py_NE) || !PyCode_Check(self) || !PyCode_Check(other)) { - Py_INCREF(Py_NotImplemented); - return Py_NotImplemented; + Py_RETURN_NOTIMPLEMENTED; } co = (PyCodeObject *)self; -- cgit v1.2.1 From d1d013c01c268d869597b35cbcd8b5d7c5baf2ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20v=2E=20L=C3=B6wis?= Date: Wed, 28 Sep 2011 07:41:54 +0200 Subject: Implement PEP 393. --- Objects/codeobject.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'Objects/codeobject.c') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 3f77718f2c..0489c7b981 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -8,19 +8,24 @@ /* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */ static int -all_name_chars(Py_UNICODE *s) +all_name_chars(PyObject *o) { static char ok_name_char[256]; static unsigned char *name_chars = (unsigned char *)NAME_CHARS; + PyUnicodeObject *u = (PyUnicodeObject *)o; + const unsigned char *s; + + if (!PyUnicode_Check(o) || PyUnicode_READY(u) == -1 || + PyUnicode_MAX_CHAR_VALUE(u) >= 128) + return 0; if (ok_name_char[*name_chars] == 0) { unsigned char *p; for (p = name_chars; *p; p++) ok_name_char[*p] = 1; } + s = PyUnicode_1BYTE_DATA(u); while (*s) { - if (*s >= 128) - return 0; if (ok_name_char[*s++] == 0) return 0; } @@ -77,9 +82,7 @@ PyCode_New(int argcount, int kwonlyargcount, /* Intern selected string constants */ for (i = PyTuple_GET_SIZE(consts); --i >= 0; ) { PyObject *v = PyTuple_GetItem(consts, i); - if (!PyUnicode_Check(v)) - continue; - if (!all_name_chars(PyUnicode_AS_UNICODE(v))) + if (!all_name_chars(v)) continue; PyUnicode_InternInPlace(&PyTuple_GET_ITEM(consts, i)); } -- cgit v1.2.1 From cb77cacedba65cf061a7e9b1da7812f0cbab4967 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 11 Oct 2011 21:53:24 +0200 Subject: Reuse PyUnicode_Copy() in validate_and_copy_tuple() --- Objects/codeobject.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'Objects/codeobject.c') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 0489c7b981..c5057bdeb9 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -249,9 +249,7 @@ validate_and_copy_tuple(PyObject *tup) return NULL; } else { - item = PyUnicode_FromUnicode( - PyUnicode_AS_UNICODE(item), - PyUnicode_GET_SIZE(item)); + item = PyUnicode_Copy(item); if (item == NULL) { Py_DECREF(newtuple); return NULL; -- cgit v1.2.1 From e38411c75cb7e29d3259e1bea81d3997e4f598dd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 12 Dec 2011 01:53:47 +0100 Subject: Make PyUnicode_Copy() private => _PyUnicode_Copy() Undocument the function. Make also decode_utf8_errors() as private (static). --- Objects/codeobject.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'Objects/codeobject.c') diff --git a/Objects/codeobject.c b/Objects/codeobject.c index c5057bdeb9..550e28498d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -249,7 +249,7 @@ validate_and_copy_tuple(PyObject *tup) return NULL; } else { - item = PyUnicode_Copy(item); + item = _PyUnicode_Copy(item); if (item == NULL) { Py_DECREF(newtuple); return NULL; -- cgit v1.2.1