frameobject.c 13 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 PyMemberDef 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
	{"f_globals",	T_OBJECT,	OFF(f_globals),	RO},
	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
19
	{"f_restricted",T_INT,		OFF(f_restricted),RO},
20 21 22
	{"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
23 24 25
	{NULL}	/* Sentinel */
};

Guido van Rossum's avatar
Guido van Rossum committed
26
static PyObject *
27
frame_getlocals(PyFrameObject *f, void *closure)
Guido van Rossum's avatar
Guido van Rossum committed
28
{
29 30 31
	PyFrame_FastToLocals(f);
	Py_INCREF(f->f_locals);
	return f->f_locals;
Guido van Rossum's avatar
Guido van Rossum committed
32 33
}

Michael W. Hudson's avatar
Michael W. Hudson committed
34 35 36 37 38
static PyObject *
frame_getlineno(PyFrameObject *f, void *closure)
{
	int lineno;

39 40 41 42
	if (f->f_trace)
		lineno = f->f_lineno;
	else
		lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);
Michael W. Hudson's avatar
Michael W. Hudson committed
43 44 45 46

	return PyInt_FromLong(lineno);
}

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
static PyObject *
frame_gettrace(PyFrameObject *f, void *closure)
{
	PyObject* trace = f->f_trace;

	if (trace == NULL)
		trace = Py_None;

	Py_INCREF(trace);

	return trace;
}

static int
frame_settrace(PyFrameObject *f, PyObject* v, void *closure)
{
	/* We rely on f_lineno being accurate when f_trace is set. */

	PyObject* old_value = f->f_trace;

	Py_XINCREF(v);
	f->f_trace = v;
	
	if (v != NULL)
		f->f_lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);

	Py_XDECREF(old_value);

	return 0;
}

78
static PyGetSetDef frame_getsetlist[] = {
79
	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
Michael W. Hudson's avatar
Michael W. Hudson committed
80
	{"f_lineno",	(getter)frame_getlineno, NULL, NULL},
81
	{"f_trace",	(getter)frame_gettrace, (setter)frame_settrace, NULL},
82 83
	{0}
};
84

85 86 87 88 89 90 91
/* 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
92 93
	f_nlocals	number of locals
	f_stacksize	size of value stack
94
        ob_size         size of localsplus
95 96 97 98 99 100 101 102
   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.
103 104 105 106

   Later, MAXFREELIST was added to bound the # of frames saved on
   free_list.  Else programs creating lots of cyclic trash involving
   frames could provoke free_list into growing without bound.
107 108
*/

Guido van Rossum's avatar
Guido van Rossum committed
109
static PyFrameObject *free_list = NULL;
110 111
static int numfree = 0;		/* number of frames currently in free_list */
#define MAXFREELIST 200		/* max value for numfree */
112

Guido van Rossum's avatar
Guido van Rossum committed
113
static void
114
frame_dealloc(PyFrameObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
115
{
116
	int i, slots;
117
	PyObject **fastlocals;
118
	PyObject **p;
119

120
 	PyObject_GC_UnTrack(f);
121
	Py_TRASHCAN_SAFE_BEGIN(f)
122
	/* Kill all local variables */
123
	slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
124
	fastlocals = f->f_localsplus;
125
	for (i = slots; --i >= 0; ++fastlocals) {
Guido van Rossum's avatar
Guido van Rossum committed
126
		Py_XDECREF(*fastlocals);
127 128
	}

129
	/* Free stack */
130 131 132
	if (f->f_stacktop != NULL) {
		for (p = f->f_valuestack; p < f->f_stacktop; p++)
			Py_XDECREF(*p);
133
	}
134
	
Guido van Rossum's avatar
Guido van Rossum committed
135 136 137 138 139 140
	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);
141 142 143
	Py_XDECREF(f->f_exc_type);
	Py_XDECREF(f->f_exc_value);
	Py_XDECREF(f->f_exc_traceback);
144 145 146 147 148 149 150
	if (numfree < MAXFREELIST) {
		++numfree;
		f->f_back = free_list;
		free_list = f;
	}
	else
		PyObject_GC_Del(f);
151
	Py_TRASHCAN_SAFE_END(f)
Guido van Rossum's avatar
Guido van Rossum committed
152 153
}

Neil Schemenauer's avatar
Neil Schemenauer committed
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
static int
frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
{
	PyObject **fastlocals, **p;
	int i, err, slots;
#define VISIT(o) if (o) {if ((err = visit((PyObject *)(o), arg))) return err;}

	VISIT(f->f_back);
	VISIT(f->f_code);
	VISIT(f->f_builtins);
	VISIT(f->f_globals);
	VISIT(f->f_locals);
	VISIT(f->f_trace);
	VISIT(f->f_exc_type);
	VISIT(f->f_exc_value);
	VISIT(f->f_exc_traceback);

	/* locals */
	slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
	fastlocals = f->f_localsplus;
	for (i = slots; --i >= 0; ++fastlocals) {
		VISIT(*fastlocals);
	}

	/* stack */
	if (f->f_stacktop != NULL) {
		for (p = f->f_valuestack; p < f->f_stacktop; p++)
			VISIT(*p);
	}
	return 0;
}

static void
frame_clear(PyFrameObject *f)
{
	PyObject **fastlocals, **p;
	int i, slots;

	Py_XDECREF(f->f_exc_type);
	f->f_exc_type = NULL;

	Py_XDECREF(f->f_exc_value);
	f->f_exc_value = NULL;

	Py_XDECREF(f->f_exc_traceback);
	f->f_exc_traceback = NULL;

	Py_XDECREF(f->f_trace);
	f->f_trace = NULL;

	/* locals */
	slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
	fastlocals = f->f_localsplus;
	for (i = slots; --i >= 0; ++fastlocals) {
		if (*fastlocals != NULL) {
			Py_XDECREF(*fastlocals);
			*fastlocals = NULL;
		}
	}

	/* stack */
	if (f->f_stacktop != NULL) {
		for (p = f->f_valuestack; p < f->f_stacktop; p++) {
			Py_XDECREF(*p);
			*p = NULL;
		}
	}
}


Guido van Rossum's avatar
Guido van Rossum committed
224 225
PyTypeObject PyFrame_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
Guido van Rossum's avatar
Guido van Rossum committed
226 227
	0,
	"frame",
228 229
	sizeof(PyFrameObject),
	sizeof(PyObject *),
Neil Schemenauer's avatar
Neil Schemenauer committed
230 231
	(destructor)frame_dealloc, 		/* tp_dealloc */
	0,					/* tp_print */
232 233
	0, 					/* tp_getattr */
	0,			 		/* tp_setattr */
Neil Schemenauer's avatar
Neil Schemenauer committed
234 235 236 237 238 239 240 241
	0,					/* tp_compare */
	0,					/* tp_repr */
	0,					/* tp_as_number */
	0,					/* tp_as_sequence */
	0,					/* tp_as_mapping */
	0,					/* tp_hash */
	0,					/* tp_call */
	0,					/* tp_str */
242 243
	PyObject_GenericGetAttr,		/* tp_getattro */
	PyObject_GenericSetAttr,		/* tp_setattro */
Neil Schemenauer's avatar
Neil Schemenauer committed
244
	0,					/* tp_as_buffer */
245
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
Neil Schemenauer's avatar
Neil Schemenauer committed
246 247 248
	0,             				/* tp_doc */
 	(traverseproc)frame_traverse,		/* tp_traverse */
	(inquiry)frame_clear,			/* tp_clear */
249 250 251 252 253 254 255 256 257
	0,					/* tp_richcompare */
	0,					/* tp_weaklistoffset */
	0,					/* tp_iter */
	0,					/* tp_iternext */
	0,					/* tp_methods */
	frame_memberlist,			/* tp_members */
	frame_getsetlist,			/* tp_getset */
	0,					/* tp_base */
	0,					/* tp_dict */
Guido van Rossum's avatar
Guido van Rossum committed
258 259
};

Guido van Rossum's avatar
Guido van Rossum committed
260
PyFrameObject *
Jeremy Hylton's avatar
Jeremy Hylton committed
261
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, 
262
	    PyObject *locals)
Guido van Rossum's avatar
Guido van Rossum committed
263
{
264
	PyFrameObject *back = tstate->frame;
Guido van Rossum's avatar
Guido van Rossum committed
265 266 267
	static PyObject *builtin_object;
	PyFrameObject *f;
	PyObject *builtins;
268
	int extras, ncells, nfrees;
269

270
	if (builtin_object == NULL) {
271
		builtin_object = PyString_InternFromString("__builtins__");
272 273 274
		if (builtin_object == NULL)
			return NULL;
	}
275 276
#ifdef Py_DEBUG
	if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
Guido van Rossum's avatar
Guido van Rossum committed
277 278
	    (locals != NULL && !PyDict_Check(locals))) {
		PyErr_BadInternalCall();
Guido van Rossum's avatar
Guido van Rossum committed
279 280
		return NULL;
	}
281
#endif
Jeremy Hylton's avatar
Jeremy Hylton committed
282
	ncells = PyTuple_GET_SIZE(code->co_cellvars);
283 284
	nfrees = PyTuple_GET_SIZE(code->co_freevars);
	extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
285 286 287 288 289 290 291 292 293 294
	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;
	}
295 296
	if (builtins != NULL && !PyDict_Check(builtins))
		builtins = NULL;
297
	if (free_list == NULL) {
298
		f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras);
299
		if (f == NULL)
300
			return NULL;
301 302
	}
	else {
303 304
		assert(numfree > 0);
		--numfree;
305 306
		f = free_list;
		free_list = free_list->f_back;
307 308
		if (f->ob_size < extras) {
			f = PyObject_GC_Resize(PyFrameObject, f, extras);
309
			if (f == NULL)
310
				return NULL;
311
		}
312
		_Py_NewReference((PyObject *)f);
313
	}
314
	if (builtins == NULL) {
315
		/* No builtins!  Make up a minimal one. */
316
		builtins = PyDict_New();
317 318 319
		if (builtins == NULL || /* Give them 'None', at least. */
		    PyDict_SetItemString(builtins, "None", Py_None) < 0) {
			Py_DECREF(f);
320
			return NULL;
321
		}
322 323
	}
	else
324
		Py_INCREF(builtins);
325
	f->f_builtins = builtins;
Guido van Rossum's avatar
Guido van Rossum committed
326
	Py_XINCREF(back);
327
	f->f_back = back;
Guido van Rossum's avatar
Guido van Rossum committed
328
	Py_INCREF(code);
329
	f->f_code = code;
Guido van Rossum's avatar
Guido van Rossum committed
330
	Py_INCREF(globals);
331
	f->f_globals = globals;
332 333 334 335
	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
336
			locals = PyDict_New();
337
			if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
338
				Py_DECREF(f);
339 340
				return NULL;
			}
341
		}
342 343 344 345
	}
	else {
		if (locals == NULL)
			locals = globals;
Guido van Rossum's avatar
Guido van Rossum committed
346
		Py_INCREF(locals);
347 348
	}
	f->f_locals = locals;
349
	f->f_trace = NULL;
350
	f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
351
	f->f_tstate = tstate;
352

Michael W. Hudson's avatar
Michael W. Hudson committed
353
	f->f_lasti = -1;
354
	f->f_lineno = code->co_firstlineno;
355
	f->f_restricted = (builtins != tstate->interp->builtins);
356 357
	f->f_iblock = 0;
	f->f_nlocals = code->co_nlocals;
358 359 360
	f->f_stacksize = code->co_stacksize;
	f->f_ncells = ncells;
	f->f_nfreevars = nfrees;
Guido van Rossum's avatar
Guido van Rossum committed
361

362 363
	extras = f->f_nlocals + ncells + nfrees;
	memset(f->f_localsplus, 0, extras * sizeof(f->f_localsplus[0]));
364

365
	f->f_valuestack = f->f_localsplus + extras;
366
	f->f_stacktop = f->f_valuestack;
367
	_PyObject_GC_TRACK(f);
368
	return f;
369 370
}

Guido van Rossum's avatar
Guido van Rossum committed
371 372 373
/* Block management */

void
374
PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
Guido van Rossum's avatar
Guido van Rossum committed
375
{
Guido van Rossum's avatar
Guido van Rossum committed
376
	PyTryBlock *b;
377
	if (f->f_iblock >= CO_MAXBLOCKS)
Guido van Rossum's avatar
Guido van Rossum committed
378
		Py_FatalError("XXX block stack overflow");
Guido van Rossum's avatar
Guido van Rossum committed
379 380 381 382 383 384
	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
385
PyTryBlock *
386
PyFrame_BlockPop(PyFrameObject *f)
Guido van Rossum's avatar
Guido van Rossum committed
387
{
Guido van Rossum's avatar
Guido van Rossum committed
388
	PyTryBlock *b;
389
	if (f->f_iblock <= 0)
Guido van Rossum's avatar
Guido van Rossum committed
390
		Py_FatalError("XXX block stack underflow");
Guido van Rossum's avatar
Guido van Rossum committed
391 392 393
	b = &f->f_blockstack[--f->f_iblock];
	return b;
}
394 395 396

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

397
static void
398 399 400 401 402
map_to_dict(PyObject *map, int nmap, PyObject *dict, PyObject **values,
	    int deref)
{
	int j;
	for (j = nmap; --j >= 0; ) {
403
		PyObject *key = PyTuple_GET_ITEM(map, j);
404 405 406 407 408 409 410 411 412 413 414 415 416 417
		PyObject *value = values[j];
		if (deref)
			value = PyCell_GET(value);
		if (value == NULL) {
			if (PyDict_DelItem(dict, key) != 0)
				PyErr_Clear();
		}
		else {
			if (PyDict_SetItem(dict, key, value) != 0)
				PyErr_Clear();
		}
	}
}

418
static void
419 420 421 422 423
dict_to_map(PyObject *map, int nmap, PyObject *dict, PyObject **values,
	    int deref, int clear)
{
	int j;
	for (j = nmap; --j >= 0; ) {
424
		PyObject *key = PyTuple_GET_ITEM(map, j);
425 426
		PyObject *value = PyDict_GetItem(dict, key);
		if (deref) {
427
			if (value || clear) {
428 429 430 431
				if (PyCell_GET(values[j]) != value) {
					if (PyCell_Set(values[j], value) < 0)
						PyErr_Clear();
				}
432 433
			}
		} else if (value != NULL || clear) {
434 435 436 437 438
			if (values[j] != value) {
				Py_XINCREF(value);
				Py_XDECREF(values[j]);
				values[j] = value;
			}
439 440 441
		}
	}
}
442

443
void
444
PyFrame_FastToLocals(PyFrameObject *f)
445
{
446
	/* Merge fast locals into f->f_locals */
Guido van Rossum's avatar
Guido van Rossum committed
447 448 449
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
450 451 452
	int j;
	if (f == NULL)
		return;
453 454
	locals = f->f_locals;
	if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
455
		locals = f->f_locals = PyDict_New();
456
		if (locals == NULL) {
Guido van Rossum's avatar
Guido van Rossum committed
457
			PyErr_Clear(); /* Can't report it :-( */
458 459 460
			return;
		}
	}
461
	map = f->f_code->co_varnames;
Guido van Rossum's avatar
Guido van Rossum committed
462
	if (!PyDict_Check(locals) || !PyTuple_Check(map))
463
		return;
Guido van Rossum's avatar
Guido van Rossum committed
464
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
465
	fast = f->f_localsplus;
Guido van Rossum's avatar
Guido van Rossum committed
466
	j = PyTuple_Size(map);
467 468
	if (j > f->f_nlocals)
		j = f->f_nlocals;
469 470
	if (f->f_nlocals)
	    map_to_dict(map, j, locals, fast, 0);
471 472 473 474 475
	if (f->f_ncells || f->f_nfreevars) {
		if (!(PyTuple_Check(f->f_code->co_cellvars)
		      && PyTuple_Check(f->f_code->co_freevars))) {
			Py_DECREF(locals);
			return;
476
		}
477 478 479 480 481 482
		map_to_dict(f->f_code->co_cellvars, 
			    PyTuple_GET_SIZE(f->f_code->co_cellvars),
			    locals, fast + f->f_nlocals, 1);
		map_to_dict(f->f_code->co_freevars, 
			    PyTuple_GET_SIZE(f->f_code->co_freevars),
			    locals, fast + f->f_nlocals + f->f_ncells, 1);
483
	}
Guido van Rossum's avatar
Guido van Rossum committed
484
	PyErr_Restore(error_type, error_value, error_traceback);
485 486 487
}

void
488
PyFrame_LocalsToFast(PyFrameObject *f, int clear)
489
{
490
	/* Merge f->f_locals into fast locals */
Guido van Rossum's avatar
Guido van Rossum committed
491 492 493
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
494 495 496 497
	int j;
	if (f == NULL)
		return;
	locals = f->f_locals;
498
	map = f->f_code->co_varnames;
499
	if (locals == NULL)
500
		return;
Guido van Rossum's avatar
Guido van Rossum committed
501
	if (!PyDict_Check(locals) || !PyTuple_Check(map))
502
		return;
Guido van Rossum's avatar
Guido van Rossum committed
503
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
504
	fast = f->f_localsplus;
Guido van Rossum's avatar
Guido van Rossum committed
505
	j = PyTuple_Size(map);
506 507
	if (j > f->f_nlocals)
		j = f->f_nlocals;
508 509
	if (f->f_nlocals)
	    dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear);
510 511 512 513 514 515
	if (f->f_ncells || f->f_nfreevars) {
		if (!(PyTuple_Check(f->f_code->co_cellvars)
		      && PyTuple_Check(f->f_code->co_freevars)))
			return;
		dict_to_map(f->f_code->co_cellvars, 
			    PyTuple_GET_SIZE(f->f_code->co_cellvars),
516
			    locals, fast + f->f_nlocals, 1, clear);
517 518
		dict_to_map(f->f_code->co_freevars, 
			    PyTuple_GET_SIZE(f->f_code->co_freevars),
519 520
			    locals, fast + f->f_nlocals + f->f_ncells, 1, 
			    clear);
521
	}
Guido van Rossum's avatar
Guido van Rossum committed
522
	PyErr_Restore(error_type, error_value, error_traceback);
523
}
524 525 526 527

/* Clear out the free list */

void
528
PyFrame_Fini(void)
529 530 531 532
{
	while (free_list != NULL) {
		PyFrameObject *f = free_list;
		free_list = free_list->f_back;
533
		PyObject_GC_Del(f);
534
		--numfree;
535
	}
536
	assert(numfree == 0);
537
}