summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-06-18 22:08:13 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-06-18 22:08:13 (GMT)
commit5ca576ed0a0c697c7e7547adfd0b3af010fd2053 (patch)
tree0b0db361191363b3c168a6c105030f53e181d3e5 /Python/ceval.c
parent1dad6a86de55c38da5c356c2c6d81be8ff7884b1 (diff)
downloadcpython-5ca576ed0a0c697c7e7547adfd0b3af010fd2053.zip
cpython-5ca576ed0a0c697c7e7547adfd0b3af010fd2053.tar.gz
cpython-5ca576ed0a0c697c7e7547adfd0b3af010fd2053.tar.bz2
Merging the gen-branch into the main line, at Guido's direction. Yay!
Bugfix candidate in inspect.py: it was referencing "self" outside of a method.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c676
1 files changed, 419 insertions, 257 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index f9d0325..30554d5 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -40,6 +40,7 @@ static PyObject *eval_code2(PyCodeObject *,
PyObject **, int,
PyObject *);
+static PyObject *eval_frame(PyFrameObject *);
static char *get_func_name(PyObject *);
static char *get_func_desc(PyObject *);
static PyObject *call_object(PyObject *, PyObject *, PyObject *);
@@ -106,6 +107,124 @@ static PyObject *str_line = NULL;
static PyObject *str_return = NULL;
+staticforward PyTypeObject gentype;
+
+typedef struct {
+ PyObject_HEAD
+ PyFrameObject *frame;
+ int running; /* true if generator is being executed */
+} genobject;
+
+static PyObject *
+gen_new(PyFrameObject *f)
+{
+ genobject *gen = PyObject_New(genobject, &gentype);
+ if (gen == NULL) {
+ Py_DECREF(f);
+ return NULL;
+ }
+ gen->frame = f;
+ gen->running = 0;
+ return (PyObject *)gen;
+}
+
+static void
+gen_dealloc(genobject *gen)
+{
+ Py_DECREF(gen->frame);
+ PyObject_DEL(gen);
+}
+
+static PyObject *
+gen_iternext(genobject *gen)
+{
+ PyFrameObject *f = gen->frame;
+ PyObject *result;
+
+ if (gen->running) {
+ PyErr_SetString(PyExc_ValueError,
+ "generator already executing");
+ return NULL;
+ }
+ if (f->f_stackbottom == NULL) {
+ return NULL;
+ }
+ gen->running = 1;
+ result = eval_frame(f);
+ gen->running = 0;
+ return result;
+}
+
+static PyObject *
+gen_next(genobject *gen, PyObject *args)
+{
+ PyObject *result;
+
+ if (!PyArg_ParseTuple(args, ":next"))
+ return NULL;
+
+ result = gen_iternext(gen);
+
+ if (result == NULL && !PyErr_Occurred()) {
+ PyErr_SetObject(PyExc_StopIteration, Py_None);
+ return NULL;
+ }
+
+ return result;
+}
+
+static PyObject *
+gen_getiter(PyObject *gen)
+{
+ Py_INCREF(gen);
+ return gen;
+}
+
+static struct PyMethodDef gen_methods[] = {
+ {"next", (PyCFunction)gen_next, METH_VARARGS,
+ "next() -- get the next value, or raise StopIteration"},
+ {NULL, NULL} /* Sentinel */
+};
+
+static PyObject *
+gen_getattr(genobject *gen, char *name)
+{
+ return Py_FindMethod(gen_methods, (PyObject *)gen, name);
+}
+
+statichere PyTypeObject gentype = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /* ob_size */
+ "generator", /* tp_name */
+ sizeof(genobject), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ /* methods */
+ (destructor)gen_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ (getattrfunc)gen_getattr, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_compare */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ 0, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ (getiterfunc)gen_getiter, /* tp_iter */
+ (iternextfunc)gen_iternext, /* tp_iternext */
+};
+
+
#ifdef WITH_THREAD
#ifndef DONT_HAVE_ERRNO_H
@@ -337,7 +456,8 @@ enum why_code {
WHY_RERAISE, /* Exception re-raised by 'finally' */
WHY_RETURN, /* 'return' statement */
WHY_BREAK, /* 'break' statement */
- WHY_CONTINUE /* 'continue' statement */
+ WHY_CONTINUE, /* 'continue' statement */
+ WHY_YIELD, /* 'yield' operator */
};
static enum why_code do_raise(PyObject *, PyObject *, PyObject *);
@@ -358,10 +478,8 @@ PyEval_EvalCode(PyCodeObject *co, PyObject *globals, PyObject *locals)
/* Interpreter main loop */
-static PyObject *
-eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
- PyObject **args, int argcount, PyObject **kws, int kwcount,
- PyObject **defs, int defcount, PyObject *closure)
+PyObject *
+eval_frame(PyFrameObject *f)
{
#ifdef DXPAIRS
int lastopcode = 0;
@@ -378,17 +496,17 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
register PyObject *u;
register PyObject *t;
register PyObject *stream = NULL; /* for PRINT opcodes */
- register PyFrameObject *f; /* Current frame */
register PyObject **fastlocals, **freevars;
PyObject *retval = NULL; /* Return value */
PyThreadState *tstate = PyThreadState_GET();
+ PyCodeObject *co;
unsigned char *first_instr;
#ifdef LLTRACE
int lltrace;
#endif
#if defined(Py_DEBUG) || defined(LLTRACE)
/* Make it easier to find out where we are with a debugger */
- char *filename = PyString_AsString(co->co_filename);
+ char *filename;
#endif
/* Code access macros */
@@ -426,6 +544,9 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Start of code */
+ if (f == NULL)
+ return NULL;
+
#ifdef USE_STACKCHECK
if (tstate->recursion_depth%10 == 0 && PyOS_CheckStack()) {
PyErr_SetString(PyExc_MemoryError, "Stack overflow");
@@ -433,256 +554,32 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
}
#endif
- if (globals == NULL) {
- PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals");
- return NULL;
- }
-
-#ifdef LLTRACE
- lltrace = PyDict_GetItemString(globals, "__lltrace__") != NULL;
-#endif
-
- f = PyFrame_New(tstate, /*back*/
- co, /*code*/
- globals, locals);
- if (f == NULL)
- return NULL;
-
- tstate->frame = f;
- fastlocals = f->f_localsplus;
- freevars = f->f_localsplus + f->f_nlocals;
-
- if (co->co_argcount > 0 ||
- co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
- int i;
- int n = argcount;
- PyObject *kwdict = NULL;
- if (co->co_flags & CO_VARKEYWORDS) {
- kwdict = PyDict_New();
- if (kwdict == NULL)
- goto fail;
- i = co->co_argcount;
- if (co->co_flags & CO_VARARGS)
- i++;
- SETLOCAL(i, kwdict);
- }
- if (argcount > co->co_argcount) {
- if (!(co->co_flags & CO_VARARGS)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes %s %d "
- "%sargument%s (%d given)",
- PyString_AsString(co->co_name),
- defcount ? "at most" : "exactly",
- co->co_argcount,
- kwcount ? "non-keyword " : "",
- co->co_argcount == 1 ? "" : "s",
- argcount);
- goto fail;
- }
- n = co->co_argcount;
- }
- for (i = 0; i < n; i++) {
- x = args[i];
- Py_INCREF(x);
- SETLOCAL(i, x);
- }
- if (co->co_flags & CO_VARARGS) {
- u = PyTuple_New(argcount - n);
- if (u == NULL)
- goto fail;
- SETLOCAL(co->co_argcount, u);
- for (i = n; i < argcount; i++) {
- x = args[i];
- Py_INCREF(x);
- PyTuple_SET_ITEM(u, i-n, x);
- }
- }
- for (i = 0; i < kwcount; i++) {
- PyObject *keyword = kws[2*i];
- PyObject *value = kws[2*i + 1];
- int j;
- if (keyword == NULL || !PyString_Check(keyword)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() keywords must be strings",
- PyString_AsString(co->co_name));
- goto fail;
- }
- /* XXX slow -- speed up using dictionary? */
- for (j = 0; j < co->co_argcount; j++) {
- PyObject *nm = PyTuple_GET_ITEM(
- co->co_varnames, j);
- int cmp = PyObject_RichCompareBool(
- keyword, nm, Py_EQ);
- if (cmp > 0)
- break;
- else if (cmp < 0)
- goto fail;
- }
- /* Check errors from Compare */
- if (PyErr_Occurred())
- goto fail;
- if (j >= co->co_argcount) {
- if (kwdict == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got an unexpected "
- "keyword argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
- goto fail;
- }
- PyDict_SetItem(kwdict, keyword, value);
- }
- else {
- if (GETLOCAL(j) != NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() got multiple "
- "values for keyword "
- "argument '%.400s'",
- PyString_AsString(co->co_name),
- PyString_AsString(keyword));
- goto fail;
- }
- Py_INCREF(value);
- SETLOCAL(j, value);
- }
- }
- if (argcount < co->co_argcount) {
- int m = co->co_argcount - defcount;
- for (i = argcount; i < m; i++) {
- if (GETLOCAL(i) == NULL) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes %s %d "
- "%sargument%s (%d given)",
- PyString_AsString(co->co_name),
- ((co->co_flags & CO_VARARGS) ||
- defcount) ? "at least"
- : "exactly",
- m, kwcount ? "non-keyword " : "",
- m == 1 ? "" : "s", i);
- goto fail;
- }
- }
- if (n > m)
- i = n - m;
- else
- i = 0;
- for (; i < defcount; i++) {
- if (GETLOCAL(m+i) == NULL) {
- PyObject *def = defs[i];
- Py_INCREF(def);
- SETLOCAL(m+i, def);
- }
- }
- }
- }
- else {
- if (argcount > 0 || kwcount > 0) {
- PyErr_Format(PyExc_TypeError,
- "%.200s() takes no arguments (%d given)",
- PyString_AsString(co->co_name),
- argcount + kwcount);
- goto fail;
- }
- }
- /* Allocate and initialize storage for cell vars, and copy free
- vars into frame. This isn't too efficient right now. */
- if (f->f_ncells) {
- int i = 0, j = 0, nargs, found;
- char *cellname, *argname;
- PyObject *c;
-
- nargs = co->co_argcount;
- if (co->co_flags & CO_VARARGS)
- nargs++;
- if (co->co_flags & CO_VARKEYWORDS)
- nargs++;
-
- /* Check for cells that shadow args */
- for (i = 0; i < f->f_ncells && j < nargs; ++i) {
- cellname = PyString_AS_STRING(
- PyTuple_GET_ITEM(co->co_cellvars, i));
- found = 0;
- while (j < nargs) {
- argname = PyString_AS_STRING(
- PyTuple_GET_ITEM(co->co_varnames, j));
- if (strcmp(cellname, argname) == 0) {
- c = PyCell_New(GETLOCAL(j));
- if (c == NULL)
- goto fail;
- GETLOCAL(f->f_nlocals + i) = c;
- found = 1;
- break;
- }
- j++;
- }
- if (found == 0) {
- c = PyCell_New(NULL);
- if (c == NULL)
- goto fail;
- SETLOCAL(f->f_nlocals + i, c);
- }
- }
- /* Initialize any that are left */
- while (i < f->f_ncells) {
- c = PyCell_New(NULL);
- if (c == NULL)
- goto fail;
- SETLOCAL(f->f_nlocals + i, c);
- i++;
- }
- }
- if (f->f_nfreevars) {
- int i;
- for (i = 0; i < f->f_nfreevars; ++i) {
- PyObject *o = PyTuple_GET_ITEM(closure, i);
- Py_INCREF(o);
- freevars[f->f_ncells + i] = o;
- }
- }
-
- if (tstate->sys_tracefunc != NULL) {
- /* tstate->sys_tracefunc, if defined, is a function that
- will be called on *every* entry to a code block.
- Its return value, if not None, is a function that
- will be called at the start of each executed line
- of code. (Actually, the function must return
- itself in order to continue tracing.)
- The trace functions are called with three arguments:
- a pointer to the current frame, a string indicating
- why the function is called, and an argument which
- depends on the situation. The global trace function
- (sys.trace) is also called whenever an exception
- is detected. */
- if (call_trace(&tstate->sys_tracefunc,
- &f->f_trace, f, str_call,
- Py_None/*XXX how to compute arguments now?*/)) {
- /* Trace function raised an error */
- goto fail;
- }
- }
-
- if (tstate->sys_profilefunc != NULL) {
- /* Similar for sys_profilefunc, except it needn't return
- itself and isn't called for "line" events */
- if (call_trace(&tstate->sys_profilefunc,
- (PyObject**)0, f, str_call,
- Py_None/*XXX*/)) {
- goto fail;
- }
- }
-
+ /* push frame */
if (++tstate->recursion_depth > recursion_limit) {
--tstate->recursion_depth;
PyErr_SetString(PyExc_RuntimeError,
"maximum recursion depth exceeded");
tstate->frame = f->f_back;
- Py_DECREF(f);
return NULL;
}
+ f->f_back = tstate->frame;
+ tstate->frame = f;
+
+ co = f->f_code;
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + f->f_nlocals;
_PyCode_GETCODEPTR(co, &first_instr);
- next_instr = first_instr;
- stack_pointer = f->f_valuestack;
+ next_instr = first_instr + f->f_lasti;
+ stack_pointer = f->f_stackbottom;
+ f->f_stackbottom = NULL;
+
+#ifdef LLTRACE
+ lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL;
+#endif
+#if defined(Py_DEBUG) || defined(LLTRACE)
+ filename = PyString_AsString(co->co_filename);
+#endif
why = WHY_NOT;
err = 0;
@@ -1459,6 +1356,14 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
why = WHY_RETURN;
break;
+ case YIELD_VALUE:
+ retval = POP();
+ f->f_stackbottom = stack_pointer;
+ f->f_lasti = INSTR_OFFSET();
+ why = WHY_YIELD;
+ break;
+
+
case EXEC_STMT:
w = POP();
v = POP();
@@ -1484,6 +1389,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
if (PyInt_Check(v)) {
why = (enum why_code) PyInt_AsLong(v);
if (why == WHY_RETURN ||
+ why == WHY_YIELD ||
why == CONTINUE_LOOP)
retval = POP();
}
@@ -2225,7 +2131,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Unwind stacks if a (pseudo) exception occurred */
- while (why != WHY_NOT && f->f_iblock > 0) {
+ while (why != WHY_NOT && why != WHY_YIELD && f->f_iblock > 0) {
PyTryBlock *b = PyFrame_BlockPop(f);
if (b->b_type == SETUP_LOOP && why == WHY_CONTINUE) {
@@ -2295,16 +2201,18 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
/* Pop remaining stack entries */
+ /*
while (!EMPTY()) {
v = POP();
Py_XDECREF(v);
}
+ */
- if (why != WHY_RETURN)
+ if (why != WHY_RETURN && why != WHY_YIELD)
retval = NULL;
if (f->f_trace) {
- if (why == WHY_RETURN) {
+ if (why == WHY_RETURN || why == WHY_YIELD) {
if (call_trace(&f->f_trace, &f->f_trace, f,
str_return, retval)) {
Py_XDECREF(retval);
@@ -2314,7 +2222,8 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
}
}
- if (tstate->sys_profilefunc && why == WHY_RETURN) {
+ if (tstate->sys_profilefunc &&
+ (why == WHY_RETURN || why == WHY_YIELD)) {
if (call_trace(&tstate->sys_profilefunc, (PyObject**)0,
f, str_return, retval)) {
Py_XDECREF(retval);
@@ -2325,18 +2234,272 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
reset_exc_info(tstate);
+ /* pop frame */
--tstate->recursion_depth;
+ tstate->frame = f->f_back;
- fail: /* Jump here from prelude on failure */
+ return retval;
+}
- /* Restore previous frame and release the current one */
+static PyObject *
+eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
+ PyObject **args, int argcount, PyObject **kws, int kwcount,
+ PyObject **defs, int defcount, PyObject *closure)
+{
+ register PyFrameObject *f;
+ register PyObject *retval = NULL;
+ register PyObject **fastlocals, **freevars;
+ PyThreadState *tstate = PyThreadState_GET();
+ PyObject *x, *u;
- tstate->frame = f->f_back;
- Py_DECREF(f);
+ if (globals == NULL) {
+ PyErr_SetString(PyExc_SystemError, "eval_code2: NULL globals");
+ return NULL;
+ }
+ f = PyFrame_New(tstate, /*back*/
+ co, /*code*/
+ globals, locals);
+ if (f == NULL)
+ return NULL;
+
+ fastlocals = f->f_localsplus;
+ freevars = f->f_localsplus + f->f_nlocals;
+
+ if (co->co_argcount > 0 ||
+ co->co_flags & (CO_VARARGS | CO_VARKEYWORDS)) {
+ int i;
+ int n = argcount;
+ PyObject *kwdict = NULL;
+ if (co->co_flags & CO_VARKEYWORDS) {
+ kwdict = PyDict_New();
+ if (kwdict == NULL)
+ goto fail;
+ i = co->co_argcount;
+ if (co->co_flags & CO_VARARGS)
+ i++;
+ SETLOCAL(i, kwdict);
+ }
+ if (argcount > co->co_argcount) {
+ if (!(co->co_flags & CO_VARARGS)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %s %d "
+ "%sargument%s (%d given)",
+ PyString_AsString(co->co_name),
+ defcount ? "at most" : "exactly",
+ co->co_argcount,
+ kwcount ? "non-keyword " : "",
+ co->co_argcount == 1 ? "" : "s",
+ argcount);
+ goto fail;
+ }
+ n = co->co_argcount;
+ }
+ for (i = 0; i < n; i++) {
+ x = args[i];
+ Py_INCREF(x);
+ SETLOCAL(i, x);
+ }
+ if (co->co_flags & CO_VARARGS) {
+ u = PyTuple_New(argcount - n);
+ if (u == NULL)
+ goto fail;
+ SETLOCAL(co->co_argcount, u);
+ for (i = n; i < argcount; i++) {
+ x = args[i];
+ Py_INCREF(x);
+ PyTuple_SET_ITEM(u, i-n, x);
+ }
+ }
+ for (i = 0; i < kwcount; i++) {
+ PyObject *keyword = kws[2*i];
+ PyObject *value = kws[2*i + 1];
+ int j;
+ if (keyword == NULL || !PyString_Check(keyword)) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() keywords must be strings",
+ PyString_AsString(co->co_name));
+ goto fail;
+ }
+ /* XXX slow -- speed up using dictionary? */
+ for (j = 0; j < co->co_argcount; j++) {
+ PyObject *nm = PyTuple_GET_ITEM(
+ co->co_varnames, j);
+ int cmp = PyObject_RichCompareBool(
+ keyword, nm, Py_EQ);
+ if (cmp > 0)
+ break;
+ else if (cmp < 0)
+ goto fail;
+ }
+ /* Check errors from Compare */
+ if (PyErr_Occurred())
+ goto fail;
+ if (j >= co->co_argcount) {
+ if (kwdict == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got an unexpected "
+ "keyword argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(keyword));
+ goto fail;
+ }
+ PyDict_SetItem(kwdict, keyword, value);
+ }
+ else {
+ if (GETLOCAL(j) != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() got multiple "
+ "values for keyword "
+ "argument '%.400s'",
+ PyString_AsString(co->co_name),
+ PyString_AsString(keyword));
+ goto fail;
+ }
+ Py_INCREF(value);
+ SETLOCAL(j, value);
+ }
+ }
+ if (argcount < co->co_argcount) {
+ int m = co->co_argcount - defcount;
+ for (i = argcount; i < m; i++) {
+ if (GETLOCAL(i) == NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes %s %d "
+ "%sargument%s (%d given)",
+ PyString_AsString(co->co_name),
+ ((co->co_flags & CO_VARARGS) ||
+ defcount) ? "at least"
+ : "exactly",
+ m, kwcount ? "non-keyword " : "",
+ m == 1 ? "" : "s", i);
+ goto fail;
+ }
+ }
+ if (n > m)
+ i = n - m;
+ else
+ i = 0;
+ for (; i < defcount; i++) {
+ if (GETLOCAL(m+i) == NULL) {
+ PyObject *def = defs[i];
+ Py_INCREF(def);
+ SETLOCAL(m+i, def);
+ }
+ }
+ }
+ }
+ else {
+ if (argcount > 0 || kwcount > 0) {
+ PyErr_Format(PyExc_TypeError,
+ "%.200s() takes no arguments (%d given)",
+ PyString_AsString(co->co_name),
+ argcount + kwcount);
+ goto fail;
+ }
+ }
+ /* Allocate and initialize storage for cell vars, and copy free
+ vars into frame. This isn't too efficient right now. */
+ if (f->f_ncells) {
+ int i = 0, j = 0, nargs, found;
+ char *cellname, *argname;
+ PyObject *c;
+
+ nargs = co->co_argcount;
+ if (co->co_flags & CO_VARARGS)
+ nargs++;
+ if (co->co_flags & CO_VARKEYWORDS)
+ nargs++;
+
+ /* Check for cells that shadow args */
+ for (i = 0; i < f->f_ncells && j < nargs; ++i) {
+ cellname = PyString_AS_STRING(
+ PyTuple_GET_ITEM(co->co_cellvars, i));
+ found = 0;
+ while (j < nargs) {
+ argname = PyString_AS_STRING(
+ PyTuple_GET_ITEM(co->co_varnames, j));
+ if (strcmp(cellname, argname) == 0) {
+ c = PyCell_New(GETLOCAL(j));
+ if (c == NULL)
+ goto fail;
+ GETLOCAL(f->f_nlocals + i) = c;
+ found = 1;
+ break;
+ }
+ j++;
+ }
+ if (found == 0) {
+ c = PyCell_New(NULL);
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(f->f_nlocals + i, c);
+ }
+ }
+ /* Initialize any that are left */
+ while (i < f->f_ncells) {
+ c = PyCell_New(NULL);
+ if (c == NULL)
+ goto fail;
+ SETLOCAL(f->f_nlocals + i, c);
+ i++;
+ }
+ }
+ if (f->f_nfreevars) {
+ int i;
+ for (i = 0; i < f->f_nfreevars; ++i) {
+ PyObject *o = PyTuple_GET_ITEM(closure, i);
+ Py_INCREF(o);
+ freevars[f->f_ncells + i] = o;
+ }
+ }
+
+ if (tstate->sys_tracefunc != NULL) {
+ /* tstate->sys_tracefunc, if defined, is a function that
+ will be called on *every* entry to a code block.
+ Its return value, if not None, is a function that
+ will be called at the start of each executed line
+ of code. (Actually, the function must return
+ itself in order to continue tracing.)
+ The trace functions are called with three arguments:
+ a pointer to the current frame, a string indicating
+ why the function is called, and an argument which
+ depends on the situation. The global trace function
+ (sys.trace) is also called whenever an exception
+ is detected. */
+ if (call_trace(&tstate->sys_tracefunc,
+ &f->f_trace, f, str_call,
+ Py_None/*XXX how to compute arguments now?*/)) {
+ /* Trace function raised an error */
+ goto fail;
+ }
+ }
+
+ if (tstate->sys_profilefunc != NULL) {
+ /* Similar for sys_profilefunc, except it needn't return
+ itself and isn't called for "line" events */
+ if (call_trace(&tstate->sys_profilefunc,
+ (PyObject**)0, f, str_call,
+ Py_None/*XXX*/)) {
+ goto fail;
+ }
+ }
+
+ if (co->co_flags & CO_GENERATOR) {
+ /* create a new generator that owns the ready to run frame
+ * and return that as the value */
+ return gen_new(f);
+ }
+
+ retval = eval_frame(f);
+
+ fail: /* Jump here from prelude on failure */
+
+ Py_DECREF(f);
return retval;
}
+
static void
set_exc_info(PyThreadState *tstate,
PyObject *type, PyObject *value, PyObject *tb)
@@ -2701,7 +2864,6 @@ _PyTrace_Init(void)
return 0;
}
-
PyObject *
PyEval_GetBuiltins(void)
{