frameobject.c 8.7 KB
Newer Older
1

Guido van Rossum's avatar
Guido van Rossum committed
2 3
/* Frame object implementation */

Guido van Rossum's avatar
Guido van Rossum committed
4
#include "Python.h"
Guido van Rossum's avatar
Guido van Rossum committed
5 6 7 8 9 10

#include "compile.h"
#include "frameobject.h"
#include "opcode.h"
#include "structmember.h"

Guido van Rossum's avatar
Guido van Rossum committed
11
#define OFF(x) offsetof(PyFrameObject, x)
Guido van Rossum's avatar
Guido van Rossum committed
12 13

static struct memberlist frame_memberlist[] = {
14 15
	{"f_back",	T_OBJECT,	OFF(f_back),	RO},
	{"f_code",	T_OBJECT,	OFF(f_code),	RO},
16
	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
17 18 19 20
	{"f_globals",	T_OBJECT,	OFF(f_globals),	RO},
	{"f_locals",	T_OBJECT,	OFF(f_locals),	RO},
	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
	{"f_lineno",	T_INT,		OFF(f_lineno),	RO},
21
	{"f_restricted",T_INT,		OFF(f_restricted),RO},
22
	{"f_trace",	T_OBJECT,	OFF(f_trace)},
23 24 25
	{"f_exc_type",	T_OBJECT,	OFF(f_exc_type)},
	{"f_exc_value",	T_OBJECT,	OFF(f_exc_value)},
	{"f_exc_traceback", T_OBJECT,	OFF(f_exc_traceback)},
Guido van Rossum's avatar
Guido van Rossum committed
26 27 28
	{NULL}	/* Sentinel */
};

Guido van Rossum's avatar
Guido van Rossum committed
29
static PyObject *
30
frame_getattr(PyFrameObject *f, char *name)
Guido van Rossum's avatar
Guido van Rossum committed
31
{
32
	if (strcmp(name, "f_locals") == 0)
Guido van Rossum's avatar
Guido van Rossum committed
33 34
		PyFrame_FastToLocals(f);
	return PyMember_Get((char *)f, frame_memberlist, name);
Guido van Rossum's avatar
Guido van Rossum committed
35 36
}

37
static int
38
frame_setattr(PyFrameObject *f, char *name, PyObject *value)
39
{
Guido van Rossum's avatar
Guido van Rossum committed
40
	return PyMember_Set((char *)f, frame_memberlist, name, value);
41 42
}

43 44 45 46 47 48 49
/* Stack frames are allocated and deallocated at a considerable rate.
   In an attempt to improve the speed of function calls, we maintain a
   separate free list of stack frames (just like integers are
   allocated in a special way -- see intobject.c).  When a stack frame
   is on the free list, only the following members have a meaning:
	ob_type		== &Frametype
	f_back		next item on free list, or NULL
50 51
	f_nlocals	number of locals
	f_stacksize	size of value stack
52
        f_size          size of localsplus
53 54 55 56 57 58 59 60 61 62
   Note that the value and block stacks are preserved -- this can save
   another malloc() call or two (and two free() calls as well!).
   Also note that, unlike for integers, each frame object is a
   malloc'ed object in its own right -- it is only the actual calls to
   malloc() that we are trying to save here, not the administration.
   After all, while a typical program may make millions of calls, a
   call depth of more than 20 or 30 is probably already exceptional
   unless the program contains run-away recursion.  I hope.
*/

Guido van Rossum's avatar
Guido van Rossum committed
63
static PyFrameObject *free_list = NULL;
64

Guido van Rossum's avatar
Guido van Rossum committed
65
static void
66
frame_dealloc(PyFrameObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
67
{
68 69 70
	int i;
	PyObject **fastlocals;

71
	Py_TRASHCAN_SAFE_BEGIN(f)
72 73 74
	/* Kill all local variables */
	fastlocals = f->f_localsplus;
	for (i = f->f_nlocals; --i >= 0; ++fastlocals) {
Guido van Rossum's avatar
Guido van Rossum committed
75
		Py_XDECREF(*fastlocals);
76 77
	}

Guido van Rossum's avatar
Guido van Rossum committed
78 79 80 81 82 83
	Py_XDECREF(f->f_back);
	Py_XDECREF(f->f_code);
	Py_XDECREF(f->f_builtins);
	Py_XDECREF(f->f_globals);
	Py_XDECREF(f->f_locals);
	Py_XDECREF(f->f_trace);
84 85 86
	Py_XDECREF(f->f_exc_type);
	Py_XDECREF(f->f_exc_value);
	Py_XDECREF(f->f_exc_traceback);
87 88
	f->f_back = free_list;
	free_list = f;
89
	Py_TRASHCAN_SAFE_END(f)
Guido van Rossum's avatar
Guido van Rossum committed
90 91
}

Guido van Rossum's avatar
Guido van Rossum committed
92 93
PyTypeObject PyFrame_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum's avatar
Guido van Rossum committed
94 95
	0,
	"frame",
Guido van Rossum's avatar
Guido van Rossum committed
96
	sizeof(PyFrameObject),
Guido van Rossum's avatar
Guido van Rossum committed
97
	0,
98
	(destructor)frame_dealloc, /*tp_dealloc*/
Guido van Rossum's avatar
Guido van Rossum committed
99
	0,		/*tp_print*/
100 101
	(getattrfunc)frame_getattr, /*tp_getattr*/
	(setattrfunc)frame_setattr, /*tp_setattr*/
Guido van Rossum's avatar
Guido van Rossum committed
102 103 104 105 106 107 108
	0,		/*tp_compare*/
	0,		/*tp_repr*/
	0,		/*tp_as_number*/
	0,		/*tp_as_sequence*/
	0,		/*tp_as_mapping*/
};

Guido van Rossum's avatar
Guido van Rossum committed
109
PyFrameObject *
Jeremy Hylton's avatar
Jeremy Hylton committed
110 111
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, 
	    PyObject *locals, PyObject *closure)
Guido van Rossum's avatar
Guido van Rossum committed
112
{
113
	PyFrameObject *back = tstate->frame;
Guido van Rossum's avatar
Guido van Rossum committed
114 115 116
	static PyObject *builtin_object;
	PyFrameObject *f;
	PyObject *builtins;
117
	int extras, ncells, nfrees;
118

119
	if (builtin_object == NULL) {
120
		builtin_object = PyString_InternFromString("__builtins__");
121 122 123
		if (builtin_object == NULL)
			return NULL;
	}
Guido van Rossum's avatar
Guido van Rossum committed
124 125 126 127 128
	if ((back != NULL && !PyFrame_Check(back)) ||
	    code == NULL || !PyCode_Check(code) ||
	    globals == NULL || !PyDict_Check(globals) ||
	    (locals != NULL && !PyDict_Check(locals))) {
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
129 130
		return NULL;
	}
Jeremy Hylton's avatar
Jeremy Hylton committed
131
	ncells = PyTuple_GET_SIZE(code->co_cellvars);
132 133
	nfrees = PyTuple_GET_SIZE(code->co_freevars);
	extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
134 135 136 137 138 139 140 141 142 143
	if (back == NULL || back->f_globals != globals) {
		builtins = PyDict_GetItem(globals, builtin_object);
		if (builtins != NULL && PyModule_Check(builtins))
			builtins = PyModule_GetDict(builtins);
	}
	else {
		/* If we share the globals, we share the builtins.
		   Save a lookup and a call. */
		builtins = back->f_builtins;
	}
144 145
	if (builtins != NULL && !PyDict_Check(builtins))
		builtins = NULL;
146
	if (free_list == NULL) {
147
		/* PyObject_New is inlined */
Guido van Rossum's avatar
Guido van Rossum committed
148
		f = (PyFrameObject *)
149 150
			PyObject_MALLOC(sizeof(PyFrameObject) +
					extras*sizeof(PyObject *));
151
		if (f == NULL)
Guido van Rossum's avatar
Guido van Rossum committed
152
			return (PyFrameObject *)PyErr_NoMemory();
153
		PyObject_INIT(f, &PyFrame_Type);
154
		f->f_size = extras;
155 156 157 158
	}
	else {
		f = free_list;
		free_list = free_list->f_back;
159
		if (f->f_size < extras) {
160
			f = (PyFrameObject *)
161 162
				PyObject_REALLOC(f, sizeof(PyFrameObject) +
						 extras*sizeof(PyObject *));
163
			if (f == NULL)
Guido van Rossum's avatar
Guido van Rossum committed
164
				return (PyFrameObject *)PyErr_NoMemory();
165
			f->f_size = extras;
166
		}
167
		else
168
			extras = f->f_size;
169
		PyObject_INIT(f, &PyFrame_Type);
170
	}
171
	if (builtins == NULL) {
172
		/* No builtins!  Make up a minimal one. */
173
		builtins = PyDict_New();
174 175 176
		if (builtins == NULL || /* Give them 'None', at least. */
		    PyDict_SetItemString(builtins, "None", Py_None) < 0) {
			Py_DECREF(f);
177
			return NULL;
178
		}
179 180 181 182
	}
	else
		Py_XINCREF(builtins);
	f->f_builtins = builtins;
Guido van Rossum's avatar
Guido van Rossum committed
183
	Py_XINCREF(back);
184
	f->f_back = back;
Guido van Rossum's avatar
Guido van Rossum committed
185
	Py_INCREF(code);
186
	f->f_code = code;
Guido van Rossum's avatar
Guido van Rossum committed
187
	Py_INCREF(globals);
188
	f->f_globals = globals;
189 190 191 192
	if (code->co_flags & CO_NEWLOCALS) {
		if (code->co_flags & CO_OPTIMIZED)
			locals = NULL; /* Let fast_2_locals handle it */
		else {
Guido van Rossum's avatar
Guido van Rossum committed
193
			locals = PyDict_New();
194
			if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
195
				Py_DECREF(f);
196 197
				return NULL;
			}
198
		}
199 200 201 202
	}
	else {
		if (locals == NULL)
			locals = globals;
Guido van Rossum's avatar
Guido van Rossum committed
203
		Py_INCREF(locals);
204 205
	}
	f->f_locals = locals;
206
	f->f_trace = NULL;
207
	f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
208
	f->f_tstate = tstate;
209

210
	f->f_lasti = 0;
211
	f->f_lineno = code->co_firstlineno;
212
	f->f_restricted = (builtins != tstate->interp->builtins);
213 214
	f->f_iblock = 0;
	f->f_nlocals = code->co_nlocals;
215 216 217
	f->f_stacksize = code->co_stacksize;
	f->f_ncells = ncells;
	f->f_nfreevars = nfrees;
Guido van Rossum's avatar
Guido van Rossum committed
218

219 220 221
	while (--extras >= 0)
		f->f_localsplus[extras] = NULL;

222
	f->f_valuestack = f->f_localsplus + (f->f_nlocals + ncells + nfrees);
223 224

	return f;
225 226
}

Guido van Rossum's avatar
Guido van Rossum committed
227 228 229
/* Block management */

void
230
PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
Guido van Rossum's avatar
Guido van Rossum committed
231
{
Guido van Rossum's avatar
Guido van Rossum committed
232
	PyTryBlock *b;
233
	if (f->f_iblock >= CO_MAXBLOCKS)
Guido van Rossum's avatar
Guido van Rossum committed
234
		Py_FatalError("XXX block stack overflow");
Guido van Rossum's avatar
Guido van Rossum committed
235 236 237 238 239 240
	b = &f->f_blockstack[f->f_iblock++];
	b->b_type = type;
	b->b_level = level;
	b->b_handler = handler;
}

Guido van Rossum's avatar
Guido van Rossum committed
241
PyTryBlock *
242
PyFrame_BlockPop(PyFrameObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
243
{
Guido van Rossum's avatar
Guido van Rossum committed
244
	PyTryBlock *b;
245
	if (f->f_iblock <= 0)
Guido van Rossum's avatar
Guido van Rossum committed
246
		Py_FatalError("XXX block stack underflow");
Guido van Rossum's avatar
Guido van Rossum committed
247 248 249
	b = &f->f_blockstack[--f->f_iblock];
	return b;
}
250 251 252

/* Convert between "fast" version of locals and dictionary version */

253 254
/* XXX should also copy free variables and cell variables */

255
void
256
PyFrame_FastToLocals(PyFrameObject *f)
257
{
258
	/* Merge fast locals into f->f_locals */
Guido van Rossum's avatar
Guido van Rossum committed
259 260 261
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
262 263 264
	int j;
	if (f == NULL)
		return;
265 266
	locals = f->f_locals;
	if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
267
		locals = f->f_locals = PyDict_New();
268
		if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
269
			PyErr_Clear(); /* Can't report it :-( */
270 271 272
			return;
		}
	}
273
	if (f->f_nlocals == 0)
274 275
		return;
	map = f->f_code->co_varnames;
Guido van Rossum's avatar
Guido van Rossum committed
276
	if (!PyDict_Check(locals) || !PyTuple_Check(map))
277
		return;
Guido van Rossum's avatar
Guido van Rossum committed
278
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
279
	fast = f->f_localsplus;
Guido van Rossum's avatar
Guido van Rossum committed
280
	j = PyTuple_Size(map);
281 282 283
	if (j > f->f_nlocals)
		j = f->f_nlocals;
	for (; --j >= 0; ) {
Guido van Rossum's avatar
Guido van Rossum committed
284 285
		PyObject *key = PyTuple_GetItem(map, j);
		PyObject *value = fast[j];
286
		if (value == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
287 288 289
			PyErr_Clear();
			if (PyDict_DelItem(locals, key) != 0)
				PyErr_Clear();
290 291
		}
		else {
Guido van Rossum's avatar
Guido van Rossum committed
292 293
			if (PyDict_SetItem(locals, key, value) != 0)
				PyErr_Clear();
294 295
		}
	}
Guido van Rossum's avatar
Guido van Rossum committed
296
	PyErr_Restore(error_type, error_value, error_traceback);
297 298 299
}

void
300
PyFrame_LocalsToFast(PyFrameObject *f, int clear)
301
{
302
	/* Merge f->f_locals into fast locals */
Guido van Rossum's avatar
Guido van Rossum committed
303 304 305
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
306 307 308 309
	int j;
	if (f == NULL)
		return;
	locals = f->f_locals;
310
	map = f->f_code->co_varnames;
311
	if (locals == NULL || f->f_code->co_nlocals == 0)
312
		return;
Guido van Rossum's avatar
Guido van Rossum committed
313
	if (!PyDict_Check(locals) || !PyTuple_Check(map))
314
		return;
Guido van Rossum's avatar
Guido van Rossum committed
315
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
316
	fast = f->f_localsplus;
Guido van Rossum's avatar
Guido van Rossum committed
317
	j = PyTuple_Size(map);
318 319 320
	if (j > f->f_nlocals)
		j = f->f_nlocals;
	for (; --j >= 0; ) {
Guido van Rossum's avatar
Guido van Rossum committed
321 322
		PyObject *key = PyTuple_GetItem(map, j);
		PyObject *value = PyDict_GetItem(locals, key);
323
		Py_XINCREF(value);
324
		if (value != NULL || clear) {
Guido van Rossum's avatar
Guido van Rossum committed
325
			Py_XDECREF(fast[j]);
326 327
			fast[j] = value;
		}
328
	}
Guido van Rossum's avatar
Guido van Rossum committed
329
	PyErr_Restore(error_type, error_value, error_traceback);
330
}
331 332 333 334

/* Clear out the free list */

void
335
PyFrame_Fini(void)
336 337 338 339
{
	while (free_list != NULL) {
		PyFrameObject *f = free_list;
		free_list = free_list->f_back;
340
		PyObject_DEL(f);
341 342
	}
}