Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(15)

Unified Diff: Python/ceval.c

Issue 10639: reindent.py converts newlines to platform default
Patch Set: Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Python/bltinmodule.c ('k') | Python/codecs.c » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
--- a/Python/ceval.c Tue Jul 26 09:37:46 2011 +0300
+++ b/Python/ceval.c Mon Jul 25 09:47:18 2011 -0400
@@ -491,6 +491,7 @@
} pendingcalls[NPENDINGCALLS];
static int pendingfirst = 0;
static int pendinglast = 0;
+static char pendingbusy = 0;
int
Py_AddPendingCall(int (*func)(void *), void *arg)
@@ -537,7 +538,6 @@
int
Py_MakePendingCalls(void)
{
- static int busy = 0;
int i;
int r = 0;
@@ -552,9 +552,9 @@
if (main_thread && PyThread_get_thread_ident() != main_thread)
return 0;
/* don't perform recursive pending calls */
- if (busy)
+ if (pendingbusy)
return 0;
- busy = 1;
+ pendingbusy = 1;
/* perform a bounded number of calls, in case of recursion */
for (i=0; i<NPENDINGCALLS; i++) {
int j;
@@ -583,7 +583,7 @@
if (r)
break;
}
- busy = 0;
+ pendingbusy = 0;
return r;
}
@@ -749,9 +749,6 @@
WHY_SILENCED = 0x0080 /* Exception silenced by 'with' */
};
-static void save_exc_state(PyThreadState *, PyFrameObject *);
-static void swap_exc_state(PyThreadState *, PyFrameObject *);
-static void restore_and_clear_exc_state(PyThreadState *, PyFrameObject *);
static enum why_code do_raise(PyObject *, PyObject *);
static int unpack_iterable(PyObject *, int, int, PyObject **);
@@ -1113,8 +1110,42 @@
Py_XDECREF(traceback); \
}
+#define SAVE_EXC_STATE() \
+ { \
+ PyObject *type, *value, *traceback; \
+ Py_XINCREF(tstate->exc_type); \
+ Py_XINCREF(tstate->exc_value); \
+ Py_XINCREF(tstate->exc_traceback); \
+ type = f->f_exc_type; \
+ value = f->f_exc_value; \
+ traceback = f->f_exc_traceback; \
+ f->f_exc_type = tstate->exc_type; \
+ f->f_exc_value = tstate->exc_value; \
+ f->f_exc_traceback = tstate->exc_traceback; \
+ Py_XDECREF(type); \
+ Py_XDECREF(value); \
+ Py_XDECREF(traceback); \
+ }
+
+#define SWAP_EXC_STATE() \
+ { \
+ PyObject *tmp; \
+ tmp = tstate->exc_type; \
+ tstate->exc_type = f->f_exc_type; \
+ f->f_exc_type = tmp; \
+ tmp = tstate->exc_value; \
+ tstate->exc_value = f->f_exc_value; \
+ f->f_exc_value = tmp; \
+ tmp = tstate->exc_traceback; \
+ tstate->exc_traceback = f->f_exc_traceback; \
+ f->f_exc_traceback = tmp; \
+ }
+
/* Start of code */
+ if (f == NULL)
+ return NULL;
+
/* push frame */
if (Py_EnterRecursiveCall(""))
return NULL;
@@ -1188,10 +1219,11 @@
/* We were in an except handler when we left,
restore the exception state which was put aside
(see YIELD_VALUE). */
- swap_exc_state(tstate, f);
+ SWAP_EXC_STATE();
}
- else
- save_exc_state(tstate, f);
+ else {
+ SAVE_EXC_STATE();
+ }
}
#ifdef LLTRACE
@@ -1347,6 +1379,8 @@
x to NULL, err to nonzero, or why to anything but WHY_NOT,
and that no operation that succeeds does this! */
+ /* case STOP_CODE: this is an error! */
+
TARGET(NOP)
FAST_DISPATCH();
@@ -1831,6 +1865,10 @@
retval = POP();
f->f_stacktop = stack_pointer;
why = WHY_YIELD;
+ /* Put aside the current exception state and restore
+ that of the calling frame. This only serves when
+ "yield" is used inside an except handler. */
+ SWAP_EXC_STATE();
goto fast_yield;
TARGET(POP_EXCEPT)
@@ -2967,26 +3005,6 @@
retval = NULL;
fast_yield:
- if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) {
- /* The purpose of this block is to put aside the generator's exception
- state and restore that of the calling frame. If the current
- exception state is from the caller, we clear the exception values
- on the generator frame, so they are not swapped back in latter. The
- origin of the current exception state is determined by checking for
- except handler blocks, which we must be in iff a new exception
- state came into existence in this frame. (An uncaught exception
- would have why == WHY_EXCEPTION, and we wouldn't be here). */
- int i;
- for (i = 0; i < f->f_iblock; i++)
- if (f->f_blockstack[i].b_type == EXCEPT_HANDLER)
- break;
- if (i == f->f_iblock)
- /* We did not create this exception. */
- restore_and_clear_exc_state(tstate, f);
- else
- swap_exc_state(tstate, f);
- }
-
if (tstate->use_tracing) {
if (tstate->c_tracefunc) {
if (why == WHY_RETURN || why == WHY_YIELD) {
@@ -3028,118 +3046,28 @@
}
static void
-format_missing(const char *kind, PyCodeObject *co, PyObject *names)
-{
- int err;
- Py_ssize_t len = PyList_GET_SIZE(names);
- PyObject *name_str, *comma, *tail, *tmp;
-
- assert(PyList_CheckExact(names));
- assert(len >= 1);
- /* Deal with the joys of natural language. */
- switch (len) {
- case 1:
- name_str = PyList_GET_ITEM(names, 0);
- Py_INCREF(name_str);
- break;
- case 2:
- name_str = PyUnicode_FromFormat("%U and %U",
- PyList_GET_ITEM(names, len - 2),
- PyList_GET_ITEM(names, len - 1));
- break;
- default:
- tail = PyUnicode_FromFormat(", %U, and %U",
- PyList_GET_ITEM(names, len - 2),
- PyList_GET_ITEM(names, len - 1));
- /* Chop off the last two objects in the list. This shouldn't actually
- fail, but we can't be too careful. */
- err = PyList_SetSlice(names, len - 2, len, NULL);
- if (err == -1) {
- Py_DECREF(tail);
- return;
- }
- /* Stitch everything up into a nice comma-separated list. */
- comma = PyUnicode_FromString(", ");
- if (comma == NULL) {
- Py_DECREF(tail);
- return;
- }
- tmp = PyUnicode_Join(comma, names);
- Py_DECREF(comma);
- if (tmp == NULL) {
- Py_DECREF(tail);
- return;
- }
- name_str = PyUnicode_Concat(tmp, tail);
- Py_DECREF(tmp);
- Py_DECREF(tail);
- break;
- }
- if (name_str == NULL)
- return;
- PyErr_Format(PyExc_TypeError,
- "%U() missing %i required %s argument%s: %U",
- co->co_name,
- len,
- kind,
- len == 1 ? "" : "s",
- name_str);
- Py_DECREF(name_str);
-}
-
-static void
-missing_arguments(PyCodeObject *co, int missing, int defcount,
- PyObject **fastlocals)
-{
- int i, j = 0;
- int start, end;
- int positional = defcount != -1;
- const char *kind = positional ? "positional" : "keyword-only";
- PyObject *missing_names;
-
- /* Compute the names of the arguments that are missing. */
- missing_names = PyList_New(missing);
- if (missing_names == NULL)
- return;
- if (positional) {
- start = 0;
- end = co->co_argcount - defcount;
- }
- else {
- start = co->co_argcount;
- end = start + co->co_kwonlyargcount;
- }
- for (i = start; i < end; i++) {
- if (GETLOCAL(i) == NULL) {
- PyObject *raw = PyTuple_GET_ITEM(co->co_varnames, i);
- PyObject *name = PyObject_Repr(raw);
- if (name == NULL) {
- Py_DECREF(missing_names);
- return;
- }
- PyList_SET_ITEM(missing_names, j++, name);
- }
- }
- assert(j == missing);
- format_missing(kind, co, missing_names);
- Py_DECREF(missing_names);
-}
-
-static void
-too_many_positional(PyCodeObject *co, int given, int defcount, PyObject **fastlocals)
+positional_argument_error(PyCodeObject *co, int given, int defcount, PyObject **fastlocals)
{
int plural;
int kwonly_given = 0;
+ int atleast = co->co_argcount - defcount;
int i;
PyObject *sig, *kwonly_sig;
- assert((co->co_flags & CO_VARARGS) == 0);
- /* Count missing keyword-only args. */
+ if (given == -1) {
+ given = 0;
+ for (i = 0; i < co->co_argcount; i++)
+ if (GETLOCAL(i))
+ given++;
+ }
for (i = co->co_argcount; i < co->co_argcount + co->co_kwonlyargcount; i++)
- if (GETLOCAL(i) != NULL)
+ if (GETLOCAL(i))
kwonly_given++;
- if (defcount) {
- int atleast = co->co_argcount - defcount;
+ if (co->co_flags & CO_VARARGS) {
+ plural = atleast != 1;
+ sig = PyUnicode_FromFormat("at least %d", atleast);
+ }
+ else if (defcount) {
plural = 1;
sig = PyUnicode_FromFormat("from %d to %d", atleast, co->co_argcount);
}
@@ -3161,7 +3089,6 @@
else {
/* This will not fail. */
kwonly_sig = PyUnicode_FromString("");
- assert(kwonly_sig != NULL);
}
PyErr_Format(PyExc_TypeError,
"%U() takes %U positional argument%s but %d%U %s given",
@@ -3290,18 +3217,16 @@
SETLOCAL(j, value);
}
if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
- too_many_positional(co, argcount, defcount, fastlocals);
+ positional_argument_error(co, argcount, defcount, fastlocals);
goto fail;
}
if (argcount < co->co_argcount) {
int m = co->co_argcount - defcount;
- int missing = 0;
- for (i = argcount; i < m; i++)
- if (GETLOCAL(i) == NULL)
- missing++;
- if (missing) {
- missing_arguments(co, missing, defcount, fastlocals);
- goto fail;
+ for (i = argcount; i < m; i++) {
+ if (GETLOCAL(i) == NULL) {
+ positional_argument_error(co, -1, defcount, fastlocals);
+ goto fail;
+ }
}
if (n > m)
i = n - m;
@@ -3316,7 +3241,6 @@
}
}
if (co->co_kwonlyargcount > 0) {
- int missing = 0;
for (i = co->co_argcount; i < total_args; i++) {
PyObject *name;
if (GETLOCAL(i) != NULL)
@@ -3330,33 +3254,64 @@
continue;
}
}
- missing++;
- }
- if (missing) {
- missing_arguments(co, missing, -1, fastlocals);
+ PyErr_Format(PyExc_TypeError,
+ "%U() requires keyword-only argument '%S'",
+ co->co_name, name);
goto fail;
}
}
/* Allocate and initialize storage for cell vars, and copy free
- vars into frame. */
- for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
+ vars into frame. This isn't too efficient right now. */
+ if (PyTuple_GET_SIZE(co->co_cellvars)) {
+ int i, j, nargs, found;
+ Py_UNICODE *cellname, *argname;
PyObject *c;
- int arg;
- /* Possibly account for the cell variable being an argument. */
- if (co->co_cell2arg != NULL &&
- (arg = co->co_cell2arg[i]) != CO_CELL_NOT_AN_ARG)
- c = PyCell_New(GETLOCAL(arg));
- else
- c = PyCell_New(NULL);
- if (c == NULL)
- goto fail;
- SETLOCAL(co->co_nlocals + i, c);
+
+ nargs = total_args;
+ if (co->co_flags & CO_VARARGS)
+ nargs++;
+ if (co->co_flags & CO_VARKEYWORDS)
+ nargs++;
+
+ /* Initialize each cell var, taking into account
+ cell vars that are initialized from arguments.
+
+ Should arrange for the compiler to put cellvars
+ that are arguments at the beginning of the cellvars
+ list so that we can march over it more efficiently?
+ */
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_cellvars); ++i) {
+ cellname = PyUnicode_AS_UNICODE(
+ PyTuple_GET_ITEM(co->co_cellvars, i));
+ found = 0;
+ for (j = 0; j < nargs; j++) {
+ argname = PyUnicode_AS_UNICODE(
+ PyTuple_GET_ITEM(co->co_varnames, j));
+ if (Py_UNICODE_strcmp(cellname, argname) == 0) {
+ c = PyCell_New(GETLOCAL(j));
+ if (c == NULL)
+ goto fail;
+ GETLOCAL(co->co_nlocals + i) = c;
+ found = 1;
+ break;
+ }
+ }
+ if (found == 0) {
+ c = PyCell_New(NULL);
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(co->co_nlocals + i, c);
+ }
+ }
}
- for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
- PyObject *o = PyTuple_GET_ITEM(closure, i);
- Py_INCREF(o);
- freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
+ if (PyTuple_GET_SIZE(co->co_freevars)) {
+ int i;
+ for (i = 0; i < PyTuple_GET_SIZE(co->co_freevars); ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ freevars[PyTuple_GET_SIZE(co->co_cellvars) + i] = o;
+ }
}
if (co->co_flags & CO_GENERATOR) {
@@ -3402,60 +3357,6 @@
}
-/* These 3 functions deal with the exception state of generators. */
-
-static void
-save_exc_state(PyThreadState *tstate, PyFrameObject *f)
-{
- PyObject *type, *value, *traceback;
- Py_XINCREF(tstate->exc_type);
- Py_XINCREF(tstate->exc_value);
- Py_XINCREF(tstate->exc_traceback);
- type = f->f_exc_type;
- value = f->f_exc_value;
- traceback = f->f_exc_traceback;
- f->f_exc_type = tstate->exc_type;
- f->f_exc_value = tstate->exc_value;
- f->f_exc_traceback = tstate->exc_traceback;
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
-}
-
-static void
-swap_exc_state(PyThreadState *tstate, PyFrameObject *f)
-{
- PyObject *tmp;
- tmp = tstate->exc_type;
- tstate->exc_type = f->f_exc_type;
- f->f_exc_type = tmp;
- tmp = tstate->exc_value;
- tstate->exc_value = f->f_exc_value;
- f->f_exc_value = tmp;
- tmp = tstate->exc_traceback;
- tstate->exc_traceback = f->f_exc_traceback;
- f->f_exc_traceback = tmp;
-}
-
-static void
-restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f)
-{
- PyObject *type, *value, *tb;
- type = tstate->exc_type;
- value = tstate->exc_value;
- tb = tstate->exc_traceback;
- tstate->exc_type = f->f_exc_type;
- tstate->exc_value = f->f_exc_value;
- tstate->exc_traceback = f->f_exc_traceback;
- f->f_exc_type = NULL;
- f->f_exc_value = NULL;
- f->f_exc_traceback = NULL;
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
-}
-
-
/* Logic for the raise statement (too complicated for inlining).
This *consumes* a reference count to each of its arguments. */
static enum why_code
@@ -3492,13 +3393,6 @@
value = PyObject_CallObject(exc, NULL);
if (value == NULL)
goto raise_error;
- if (!PyExceptionInstance_Check(value)) {
- PyErr_Format(PyExc_TypeError,
- "calling %R should have returned an instance of "
- "BaseException, not %R",
- type, Py_TYPE(value));
- goto raise_error;
- }
}
else if (PyExceptionInstance_Check(exc)) {
value = exc;
« no previous file with comments | « Python/bltinmodule.c ('k') | Python/codecs.c » ('j') | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+