/* Frame object implementation */

#include "Python.h"

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

#undef MIN
#undef MAX
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))

#define OFF(x) offsetof(PyFrameObject, x)

static PyMemberDef frame_memberlist[] = {
	{"f_back",	T_OBJECT,	OFF(f_back),	RO},
	{"f_code",	T_OBJECT,	OFF(f_code),	RO},
	{"f_builtins",	T_OBJECT,	OFF(f_builtins),RO},
	{"f_globals",	T_OBJECT,	OFF(f_globals),	RO},
	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
	{"f_restricted",T_INT,		OFF(f_restricted),RO},
	{"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)},
	{NULL}	/* Sentinel */
};

static PyObject *
frame_getlocals(PyFrameObject *f, void *closure)
{
	PyFrame_FastToLocals(f);
	Py_INCREF(f->f_locals);
	return f->f_locals;
}

static PyObject *
frame_getlineno(PyFrameObject *f, void *closure)
{
	int lineno;

	if (f->f_trace)
		lineno = f->f_lineno;
	else
		lineno = PyCode_Addr2Line(f->f_code, f->f_lasti);

	return PyInt_FromLong(lineno);
}

/* Setter for f_lineno - you can set f_lineno from within a trace function in
 * order to jump to a given line of code, subject to some restrictions.  Most
 * lines are OK to jump to because they don't make any assumptions about the
 * state of the stack (obvious because you could remove the line and the code
 * would still work without any stack errors), but there are some constructs
 * that limit jumping:
 *
 *  o Lines with an 'except' statement on them can't be jumped to, because
 *    they expect an exception to be on the top of the stack.
 *  o Lines that live in a 'finally' block can't be jumped from or to, since
 *    the END_FINALLY expects to clean up the stack after the 'try' block.
 *  o 'try'/'for'/'while' blocks can't be jumped into because the blockstack
 *    needs to be set up before their code runs, and for 'for' loops the
 *    iterator needs to be on the stack.
 */
static int
frame_setlineno(PyFrameObject *f, PyObject* p_new_lineno)
{
	int new_lineno = 0;		/* The new value of f_lineno */
	int new_lasti = 0;		/* The new value of f_lasti */
	int new_iblock = 0;		/* The new value of f_iblock */
	char *code = NULL;		/* The bytecode for the frame... */
	Py_ssize_t code_len = 0;	/* ...and its length */
	char *lnotab = NULL;		/* Iterating over co_lnotab */
	Py_ssize_t lnotab_len = 0;	/* (ditto) */
	int offset = 0;			/* (ditto) */
	int line = 0;			/* (ditto) */
	int addr = 0;			/* (ditto) */
	int min_addr = 0;		/* Scanning the SETUPs and POPs */
	int max_addr = 0;		/* (ditto) */
	int delta_iblock = 0;		/* (ditto) */
	int min_delta_iblock = 0;	/* (ditto) */
	int min_iblock = 0;		/* (ditto) */
	int f_lasti_setup_addr = 0;	/* Policing no-jump-into-finally */
	int new_lasti_setup_addr = 0;	/* (ditto) */
	int blockstack[CO_MAXBLOCKS];	/* Walking the 'finally' blocks */
	int in_finally[CO_MAXBLOCKS];	/* (ditto) */
	int blockstack_top = 0;		/* (ditto) */
	int setup_op = 0;               /* (ditto) */

	/* f_lineno must be an integer. */
	if (!PyInt_Check(p_new_lineno)) {
		PyErr_SetString(PyExc_ValueError,
				"lineno must be an integer");
		return -1;
	}

	/* You can only do this from within a trace function, not via
	 * _getframe or similar hackery. */
	if (!f->f_trace)
	{
		PyErr_Format(PyExc_ValueError,
			     "f_lineno can only be set by a trace function");
		return -1;
	}

	/* Fail if the line comes before the start of the code block. */
	new_lineno = (int) PyInt_AsLong(p_new_lineno);
	if (new_lineno < f->f_code->co_firstlineno) {
		PyErr_Format(PyExc_ValueError,
			     "line %d comes before the current code block",
			     new_lineno);
		return -1;
	}

	/* Find the bytecode offset for the start of the given line, or the
	 * first code-owning line after it. */
	PyString_AsStringAndSize(f->f_code->co_lnotab, &lnotab, &lnotab_len);
	addr = 0;
	line = f->f_code->co_firstlineno;
	new_lasti = -1;
	for (offset = 0; offset < lnotab_len; offset += 2) {
		addr += lnotab[offset];
		line += lnotab[offset+1];
		if (line >= new_lineno) {
			new_lasti = addr;
			new_lineno = line;
			break;
		}
	}

	/* If we didn't reach the requested line, return an error. */
	if (new_lasti == -1) {
		PyErr_Format(PyExc_ValueError,
			     "line %d comes after the current code block",
			     new_lineno);
		return -1;
	}

	/* We're now ready to look at the bytecode. */
	PyString_AsStringAndSize(f->f_code->co_code, &code, &code_len);
	min_addr = MIN(new_lasti, f->f_lasti);
	max_addr = MAX(new_lasti, f->f_lasti);

	/* You can't jump onto a line with an 'except' statement on it -
	 * they expect to have an exception on the top of the stack, which
	 * won't be true if you jump to them.  They always start with code
	 * that either pops the exception using POP_TOP (plain 'except:'
	 * lines do this) or duplicates the exception on the stack using
	 * DUP_TOP (if there's an exception type specified).  See compile.c,
	 * 'com_try_except' for the full details.  There aren't any other
	 * cases (AFAIK) where a line's code can start with DUP_TOP or
	 * POP_TOP, but if any ever appear, they'll be subject to the same
	 * restriction (but with a different error message). */
	if (code[new_lasti] == DUP_TOP || code[new_lasti] == POP_TOP) {
		PyErr_SetString(PyExc_ValueError,
		    "can't jump to 'except' line as there's no exception");
		return -1;
	}

	/* You can't jump into or out of a 'finally' block because the 'try'
	 * block leaves something on the stack for the END_FINALLY to clean
	 * up.  So we walk the bytecode, maintaining a simulated blockstack.
	 * When we reach the old or new address and it's in a 'finally' block
	 * we note the address of the corresponding SETUP_FINALLY.  The jump
	 * is only legal if neither address is in a 'finally' block or
	 * they're both in the same one.  'blockstack' is a stack of the
	 * bytecode addresses of the SETUP_X opcodes, and 'in_finally' tracks
	 * whether we're in a 'finally' block at each blockstack level. */
	f_lasti_setup_addr = -1;
	new_lasti_setup_addr = -1;
	memset(blockstack, '\0', sizeof(blockstack));
	memset(in_finally, '\0', sizeof(in_finally));
	blockstack_top = 0;
	for (addr = 0; addr < code_len; addr++) {
		unsigned char op = code[addr];
		switch (op) {
		case SETUP_LOOP:
		case SETUP_EXCEPT:
		case SETUP_FINALLY:
			blockstack[blockstack_top++] = addr;
			in_finally[blockstack_top-1] = 0;
			break;

		case POP_BLOCK:
			assert(blockstack_top > 0);
			setup_op = code[blockstack[blockstack_top-1]];
			if (setup_op == SETUP_FINALLY) {
				in_finally[blockstack_top-1] = 1;
			}
			else {
				blockstack_top--;
			}
			break;

		case END_FINALLY:
			/* Ignore END_FINALLYs for SETUP_EXCEPTs - they exist
			 * in the bytecode but don't correspond to an actual
			 * 'finally' block.  (If blockstack_top is 0, we must
			 * be seeing such an END_FINALLY.) */
			if (blockstack_top > 0) {
				setup_op = code[blockstack[blockstack_top-1]];
				if (setup_op == SETUP_FINALLY) {
					blockstack_top--;
				}
			}
			break;
		}

		/* For the addresses we're interested in, see whether they're
		 * within a 'finally' block and if so, remember the address
		 * of the SETUP_FINALLY. */
		if (addr == new_lasti || addr == f->f_lasti) {
			int i = 0;
			int setup_addr = -1;
			for (i = blockstack_top-1; i >= 0; i--) {
				if (in_finally[i]) {
					setup_addr = blockstack[i];
					break;
				}
			}

			if (setup_addr != -1) {
				if (addr == new_lasti) {
					new_lasti_setup_addr = setup_addr;
				}

				if (addr == f->f_lasti) {
					f_lasti_setup_addr = setup_addr;
				}
			}
		}

		if (op >= HAVE_ARGUMENT) {
			addr += 2;
		}
	}

	/* Verify that the blockstack tracking code didn't get lost. */
	assert(blockstack_top == 0);

	/* After all that, are we jumping into / out of a 'finally' block? */
	if (new_lasti_setup_addr != f_lasti_setup_addr) {
		PyErr_SetString(PyExc_ValueError,
			    "can't jump into or out of a 'finally' block");
		return -1;
	}


	/* Police block-jumping (you can't jump into the middle of a block)
	 * and ensure that the blockstack finishes up in a sensible state (by
	 * popping any blocks we're jumping out of).  We look at all the
	 * blockstack operations between the current position and the new
	 * one, and keep track of how many blocks we drop out of on the way.
	 * By also keeping track of the lowest blockstack position we see, we
	 * can tell whether the jump goes into any blocks without coming out
	 * again - in that case we raise an exception below. */
	delta_iblock = 0;
	for (addr = min_addr; addr < max_addr; addr++) {
		unsigned char op = code[addr];
		switch (op) {
		case SETUP_LOOP:
		case SETUP_EXCEPT:
		case SETUP_FINALLY:
			delta_iblock++;
			break;

		case POP_BLOCK:
			delta_iblock--;
			break;
		}

		min_delta_iblock = MIN(min_delta_iblock, delta_iblock);

		if (op >= HAVE_ARGUMENT) {
			addr += 2;
		}
	}

	/* Derive the absolute iblock values from the deltas. */
	min_iblock = f->f_iblock + min_delta_iblock;
	if (new_lasti > f->f_lasti) {
		/* Forwards jump. */
		new_iblock = f->f_iblock + delta_iblock;
	}
	else {
		/* Backwards jump. */
		new_iblock = f->f_iblock - delta_iblock;
	}

	/* Are we jumping into a block? */
	if (new_iblock > min_iblock) {
		PyErr_SetString(PyExc_ValueError,
				"can't jump into the middle of a block");
		return -1;
	}

	/* Pop any blocks that we're jumping out of. */
	while (f->f_iblock > new_iblock) {
		PyTryBlock *b = &f->f_blockstack[--f->f_iblock];
		while ((f->f_stacktop - f->f_valuestack) > b->b_level) {
			PyObject *v = (*--f->f_stacktop);
			Py_DECREF(v);
		}
	}

	/* Finally set the new f_lineno and f_lasti and return OK. */
	f->f_lineno = new_lineno;
	f->f_lasti = new_lasti;
	return 0;
}

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

static PyGetSetDef frame_getsetlist[] = {
	{"f_locals",	(getter)frame_getlocals, NULL, NULL},
	{"f_lineno",	(getter)frame_getlineno,
			(setter)frame_setlineno, NULL},
	{"f_trace",	(getter)frame_gettrace, (setter)frame_settrace, NULL},
	{0}
};

/* 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
	f_nlocals	number of locals
	f_stacksize	size of value stack
        ob_size         size of localsplus
   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.

   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.
*/

static PyFrameObject *free_list = NULL;
static int numfree = 0;		/* number of frames currently in free_list */
#define MAXFREELIST 200		/* max value for numfree */

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

 	PyObject_GC_UnTrack(f);
	Py_TRASHCAN_SAFE_BEGIN(f)
	/* Kill all local variables */
	slots = f->f_nlocals + f->f_ncells + f->f_nfreevars;
	fastlocals = f->f_localsplus;
	for (i = slots; --i >= 0; ++fastlocals) {
		Py_XDECREF(*fastlocals);
	}

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

	Py_XDECREF(f->f_back);
	Py_DECREF(f->f_code);
	Py_DECREF(f->f_builtins);
	Py_DECREF(f->f_globals);
	Py_XDECREF(f->f_locals);
	Py_XDECREF(f->f_trace);
	Py_XDECREF(f->f_exc_type);
	Py_XDECREF(f->f_exc_value);
	Py_XDECREF(f->f_exc_traceback);
	if (numfree < MAXFREELIST) {
		++numfree;
		f->f_back = free_list;
		free_list = f;
	}
	else
		PyObject_GC_Del(f);
	Py_TRASHCAN_SAFE_END(f)
}

static int
frame_traverse(PyFrameObject *f, visitproc visit, void *arg)
{
	PyObject **fastlocals, **p;
	int i, slots;

	Py_VISIT(f->f_back);
	Py_VISIT(f->f_code);
	Py_VISIT(f->f_builtins);
	Py_VISIT(f->f_globals);
	Py_VISIT(f->f_locals);
	Py_VISIT(f->f_trace);
	Py_VISIT(f->f_exc_type);
	Py_VISIT(f->f_exc_value);
	Py_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)
		Py_VISIT(*fastlocals);

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

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

	/* Before anything else, make sure that this frame is clearly marked
         * as being defunct!  Else, e.g., a generator reachable from this
         * frame may also point to this frame, believe itself to still be
         * active, and try cleaning up this frame again.
         */
	oldtop = f->f_stacktop;
        f->f_stacktop = NULL;

	Py_CLEAR(f->f_exc_type);
	Py_CLEAR(f->f_exc_value);
	Py_CLEAR(f->f_exc_traceback);
	Py_CLEAR(f->f_trace);

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

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


PyTypeObject PyFrame_Type = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"frame",
	sizeof(PyFrameObject),
	sizeof(PyObject *),
	(destructor)frame_dealloc, 		/* tp_dealloc */
	0,					/* tp_print */
	0, 					/* tp_getattr */
	0,			 		/* tp_setattr */
	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 */
	PyObject_GenericGetAttr,		/* tp_getattro */
	PyObject_GenericSetAttr,		/* tp_setattro */
	0,					/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
	0,             				/* tp_doc */
 	(traverseproc)frame_traverse,		/* tp_traverse */
	(inquiry)frame_clear,			/* tp_clear */
	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 */
};

static PyObject *builtin_object;

int _PyFrame_Init()
{
	builtin_object = PyString_InternFromString("__builtins__");
	return (builtin_object != NULL);
}

PyFrameObject *
PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals,
	    PyObject *locals)
{
	PyFrameObject *back = tstate->frame;
	PyFrameObject *f;
	PyObject *builtins;
	Py_ssize_t extras, ncells, nfrees, i;

#ifdef Py_DEBUG
	if (code == NULL || globals == NULL || !PyDict_Check(globals) ||
	    (locals != NULL && !PyMapping_Check(locals))) {
		PyErr_BadInternalCall();
		return NULL;
	}
#endif
	ncells = PyTuple_GET_SIZE(code->co_cellvars);
	nfrees = PyTuple_GET_SIZE(code->co_freevars);
	extras = code->co_stacksize + code->co_nlocals + ncells + nfrees;
	if (back == NULL || back->f_globals != globals) {
		builtins = PyDict_GetItem(globals, builtin_object);
		if (builtins) {
			if (PyModule_Check(builtins)) {
				builtins = PyModule_GetDict(builtins);
				assert(!builtins || PyDict_Check(builtins));
			}
			else if (!PyDict_Check(builtins))
				builtins = NULL;
		}
		if (builtins == NULL) {
			/* No builtins!  Make up a minimal one
			   Give them 'None', at least. */
			builtins = PyDict_New();
			if (builtins == NULL ||
			    PyDict_SetItemString(
				    builtins, "None", Py_None) < 0)
				return NULL;
		}
		else
			Py_INCREF(builtins);

	}
	else {
		/* If we share the globals, we share the builtins.
		   Save a lookup and a call. */
		builtins = back->f_builtins;
		assert(builtins != NULL && PyDict_Check(builtins));
		Py_INCREF(builtins);
	}
	if (free_list == NULL) {
		f = PyObject_GC_NewVar(PyFrameObject, &PyFrame_Type, extras);
		if (f == NULL) {
			Py_DECREF(builtins);
			return NULL;
		}
	}
	else {
		assert(numfree > 0);
		--numfree;
		f = free_list;
		free_list = free_list->f_back;
		if (f->ob_size < extras) {
			f = PyObject_GC_Resize(PyFrameObject, f, extras);
			if (f == NULL) {
				Py_DECREF(builtins);
				return NULL;
			}
		}
		_Py_NewReference((PyObject *)f);
	}
	f->f_builtins = builtins;
	Py_XINCREF(back);
	f->f_back = back;
	Py_INCREF(code);
	f->f_code = code;
	Py_INCREF(globals);
	f->f_globals = globals;
	/* Most functions have CO_NEWLOCALS and CO_OPTIMIZED set. */
	if ((code->co_flags & (CO_NEWLOCALS | CO_OPTIMIZED)) ==
		(CO_NEWLOCALS | CO_OPTIMIZED))
		locals = NULL; /* PyFrame_FastToLocals() will set. */
	else if (code->co_flags & CO_NEWLOCALS) {
		locals = PyDict_New();
		if (locals == NULL) {
			Py_DECREF(f);
			return NULL;
		}
	}
	else {
		if (locals == NULL)
			locals = globals;
		Py_INCREF(locals);
	}
	f->f_locals = locals;
	f->f_trace = NULL;
	f->f_exc_type = f->f_exc_value = f->f_exc_traceback = NULL;
	f->f_tstate = tstate;

	f->f_lasti = -1;
	f->f_lineno = code->co_firstlineno;
	f->f_restricted = (builtins != tstate->interp->builtins);
	f->f_iblock = 0;
	f->f_nlocals = code->co_nlocals;
	f->f_stacksize = code->co_stacksize;
	f->f_ncells = ncells;
	f->f_nfreevars = nfrees;

	extras = f->f_nlocals + ncells + nfrees;
	/* Tim said it's ok to replace memset */
	for (i=0; i<extras; i++)
		f->f_localsplus[i] = NULL;

	f->f_valuestack = f->f_localsplus + extras;
	f->f_stacktop = f->f_valuestack;
	_PyObject_GC_TRACK(f);
	return f;
}

/* Block management */

void
PyFrame_BlockSetup(PyFrameObject *f, int type, int handler, int level)
{
	PyTryBlock *b;
	if (f->f_iblock >= CO_MAXBLOCKS)
		Py_FatalError("XXX block stack overflow");
	b = &f->f_blockstack[f->f_iblock++];
	b->b_type = type;
	b->b_level = level;
	b->b_handler = handler;
}

PyTryBlock *
PyFrame_BlockPop(PyFrameObject *f)
{
	PyTryBlock *b;
	if (f->f_iblock <= 0)
		Py_FatalError("XXX block stack underflow");
	b = &f->f_blockstack[--f->f_iblock];
	return b;
}

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

static void
map_to_dict(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
	    Py_ssize_t deref)
{
	Py_ssize_t j;
	for (j = nmap; --j >= 0; ) {
		PyObject *key = PyTuple_GET_ITEM(map, j);
		PyObject *value = values[j];
		if (deref)
			value = PyCell_GET(value);
		if (value == NULL) {
			if (PyObject_DelItem(dict, key) != 0)
				PyErr_Clear();
		}
		else {
			if (PyObject_SetItem(dict, key, value) != 0)
				PyErr_Clear();
		}
	}
}

static void
dict_to_map(PyObject *map, Py_ssize_t nmap, PyObject *dict, PyObject **values,
	    Py_ssize_t deref, int clear)
{
	Py_ssize_t j;
	for (j = nmap; --j >= 0; ) {
		PyObject *key = PyTuple_GET_ITEM(map, j);
		PyObject *value = PyObject_GetItem(dict, key);
		if (value == NULL)
			PyErr_Clear();
		if (deref) {
			if (value || clear) {
				if (PyCell_GET(values[j]) != value) {
					if (PyCell_Set(values[j], value) < 0)
						PyErr_Clear();
				}
			}
		} else if (value != NULL || clear) {
			if (values[j] != value) {
				Py_XINCREF(value);
				Py_XDECREF(values[j]);
				values[j] = value;
			}
		}
		Py_XDECREF(value);
	}
}

void
PyFrame_FastToLocals(PyFrameObject *f)
{
	/* Merge fast locals into f->f_locals */
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
	Py_ssize_t j;
	if (f == NULL)
		return;
	locals = f->f_locals;
	if (locals == NULL) {
		locals = f->f_locals = PyDict_New();
		if (locals == NULL) {
			PyErr_Clear(); /* Can't report it :-( */
			return;
		}
	}
	map = f->f_code->co_varnames;
	if (!PyTuple_Check(map))
		return;
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
	fast = f->f_localsplus;
	j = PyTuple_GET_SIZE(map);
	if (j > f->f_nlocals)
		j = f->f_nlocals;
	if (f->f_nlocals)
		map_to_dict(map, j, locals, fast, 0);
	if (f->f_ncells || f->f_nfreevars) {
		if (!(PyTuple_Check(f->f_code->co_cellvars)
		      && PyTuple_Check(f->f_code->co_freevars))) {
			return;
		}
		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);
	}
	PyErr_Restore(error_type, error_value, error_traceback);
}

void
PyFrame_LocalsToFast(PyFrameObject *f, int clear)
{
	/* Merge f->f_locals into fast locals */
	PyObject *locals, *map;
	PyObject **fast;
	PyObject *error_type, *error_value, *error_traceback;
	Py_ssize_t j;
	if (f == NULL)
		return;
	locals = f->f_locals;
	map = f->f_code->co_varnames;
	if (locals == NULL)
		return;
	if (!PyTuple_Check(map))
		return;
	PyErr_Fetch(&error_type, &error_value, &error_traceback);
	fast = f->f_localsplus;
	j = PyTuple_GET_SIZE(map);
	if (j > f->f_nlocals)
		j = f->f_nlocals;
	if (f->f_nlocals)
	    dict_to_map(f->f_code->co_varnames, j, locals, fast, 0, clear);
	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),
			    locals, fast + f->f_nlocals, 1, clear);
		dict_to_map(f->f_code->co_freevars,
			    PyTuple_GET_SIZE(f->f_code->co_freevars),
			    locals, fast + f->f_nlocals + f->f_ncells, 1,
			    clear);
	}
	PyErr_Restore(error_type, error_value, error_traceback);
}

/* Clear out the free list */

void
PyFrame_Fini(void)
{
	while (free_list != NULL) {
		PyFrameObject *f = free_list;
		free_list = free_list->f_back;
		PyObject_GC_Del(f);
		--numfree;
	}
	assert(numfree == 0);
	Py_XDECREF(builtin_object);
	builtin_object = NULL;
}
