summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-01-29 22:51:52 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-01-29 22:51:52 (GMT)
commit2b724da8d9cd0c41a51e798eca75018ce155e997 (patch)
tree96a1648e0d50dbbd7ae56b3b55e7b44b107362dd /Python/ceval.c
parent55087f0c351d6de453a5c95293792051d899f16b (diff)
downloadcpython-2b724da8d9cd0c41a51e798eca75018ce155e997.zip
cpython-2b724da8d9cd0c41a51e798eca75018ce155e997.tar.gz
cpython-2b724da8d9cd0c41a51e798eca75018ce155e997.tar.bz2
Remove f_closure slot of frameobject and use f_localsplus instead.
This change eliminates an extra malloc/free when a frame with free variables is created. Any cell vars or free vars are stored in f_localsplus after the locals and before the stack. eval_code2() fills in the appropriate values after handling initialization of locals. To track the size the frame has an f_size member that tracks the total size of f_localsplus. It used to be implicitly f_nlocals + f_stacksize.
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index c7b5696..5d593f2 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -368,7 +368,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
register PyObject *t;
register PyObject *stream = NULL; /* for PRINT opcodes */
register PyFrameObject *f; /* Current frame */
- register PyObject **fastlocals;
+ register PyObject **fastlocals, **freevars;
PyObject *retval = NULL; /* Return value */
PyThreadState *tstate = PyThreadState_GET();
unsigned char *first_instr;
@@ -439,6 +439,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
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)) {
@@ -572,6 +573,17 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
goto fail;
}
}
+ /* Allocate storage for cell vars and copy free vars into frame */
+ if (f->f_ncells) {
+ int i;
+ for (i = 0; i < f->f_ncells; ++i)
+ freevars[i] = PyCell_New(NULL);
+ }
+ if (f->f_nfreevars) {
+ int i;
+ for (i = 0; i < f->f_nfreevars; ++i)
+ freevars[f->f_ncells + i] = PyTuple_GET_ITEM(closure, i);
+ }
if (tstate->sys_tracefunc != NULL) {
/* tstate->sys_tracefunc, if defined, is a function that
@@ -1623,13 +1635,13 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
continue;
case LOAD_CLOSURE:
- x = PyTuple_GET_ITEM(f->f_closure, oparg);
+ x = freevars[oparg];
Py_INCREF(x);
PUSH(x);
break;
case LOAD_DEREF:
- x = PyTuple_GET_ITEM(f->f_closure, oparg);
+ x = freevars[oparg];
w = PyCell_Get(x);
Py_INCREF(w);
PUSH(w);
@@ -1637,7 +1649,7 @@ eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals,
case STORE_DEREF:
w = POP();
- x = PyTuple_GET_ITEM(f->f_closure, oparg);
+ x = freevars[oparg];
PyCell_Set(x, w);
continue;