diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-01-29 22:51:52 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-01-29 22:51:52 (GMT) |
commit | 2b724da8d9cd0c41a51e798eca75018ce155e997 (patch) | |
tree | 96a1648e0d50dbbd7ae56b3b55e7b44b107362dd /Python/ceval.c | |
parent | 55087f0c351d6de453a5c95293792051d899f16b (diff) | |
download | cpython-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.c | 20 |
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; |