diff Python/ceval.c @ 16355:e4420c2468f9 legacy-trunk

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.
author Jeremy Hylton <jeremy@alum.mit.edu>
date Mon, 29 Jan 2001 22:51:52 +0000
parents fd8c7203251f
children 50f7dd1a5357
line wrap: on
line diff
--- a/Python/ceval.c	Mon Jan 29 22:46:35 2001 +0000
+++ b/Python/ceval.c	Mon Jan 29 22:51:52 2001 +0000
@@ -368,7 +368,7 @@
 	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 @@
 
 	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 @@
 			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 @@
 			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 @@
 
 		case STORE_DEREF:
 			w = POP();
-			x = PyTuple_GET_ITEM(f->f_closure, oparg);
+			x = freevars[oparg];
 			PyCell_Set(x, w);
 			continue;