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.
This commit is contained in:
Jeremy Hylton 2001-01-29 22:51:52 +00:00
parent 55087f0c35
commit 2b724da8d9
3 changed files with 33 additions and 28 deletions

View file

@ -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;