Changes to speed up local variables enormously, by avoiding dictionary
lookup (opcode.h, ceval.[ch], compile.c, frameobject.[ch],
pythonrun.c, import.c).  The .pyc MAGIC number is changed again.
Added get_menu_text to flmodule.
diff --git a/Python/ceval.c b/Python/ceval.c
index 64f2429..45d0a6a 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -81,6 +81,7 @@
 static object *cmp_outcome PROTO((int, object *, object *));
 static int import_from PROTO((object *, object *, object *));
 static object *build_class PROTO((object *, object *));
+static void locals_2_fast PROTO((frameobject *, int));
 
 
 /* Pointer to current frame, used to link new frames to */
@@ -994,19 +995,51 @@
 			break;
 
 		case RESERVE_FAST:
-			if (oparg > 0) {
-				XDECREF(fastlocals);
-				x = newlistobject(oparg);
-				fastlocals = (listobject *) x;
+			x = GETCONST(oparg);
+			if (x == None)
+				break;
+			if (x == NULL || !is_dictobject(x)) {
+				fatal("bad RESERVE_FAST");
+				err_setstr(SystemError, "bad RESERVE_FAST");
+				x = NULL;
+				break;
 			}
+			XDECREF(f->f_fastlocals);
+			XDECREF(f->f_localmap);
+			INCREF(x);
+			f->f_localmap = x;
+			f->f_fastlocals = x = newlistobject(
+			    x->ob_type->tp_as_mapping->mp_length(x));
+			fastlocals = (listobject *) x;
 			break;
 
 		case LOAD_FAST:
-			/* NYI */
+			x = GETLISTITEM(fastlocals, oparg);
+			if (x == NULL) {
+				err_setstr(NameError,
+					   "undefined local variable");
+				break;
+			}
+			INCREF(x);
+			PUSH(x);
 			break;
 
 		case STORE_FAST:
-			/* NYI */
+			w = GETLISTITEM(fastlocals, oparg);
+			XDECREF(w);
+			w = POP();
+			GETLISTITEM(fastlocals, oparg) = w;
+			break;
+
+		case DELETE_FAST:
+			x = GETLISTITEM(fastlocals, oparg);
+			if (x == NULL) {
+				err_setstr(NameError,
+					   "undefined local variable");
+				break;
+			}
+			DECREF(x);
+			GETLISTITEM(fastlocals, oparg) = NULL;
 			break;
 		
 		case BUILD_TUPLE:
@@ -1068,6 +1101,7 @@
 			w = GETNAMEV(oparg);
 			v = TOP();
 			err = import_from(f->f_locals, v, w);
+			locals_2_fast(f, 0);
 			break;
 		
 		case JUMP_FORWARD:
@@ -1299,8 +1333,6 @@
 	
 	current_frame = f->f_back;
 	DECREF(f);
-
-	XDECREF(fastlocals);
 	
 	return retval;
 }
@@ -1418,10 +1450,92 @@
 object *
 getlocals()
 {
-	if (current_frame == NULL)
+	/* Merge f->f_fastlocals into f->f_locals, then return the latter */
+	frameobject *f;
+	object *locals, *fast, *map;
+	int i;
+	f = current_frame;
+	if (f == NULL)
 		return NULL;
-	else
-		return current_frame->f_locals;
+	locals = f->f_locals;
+	fast = f->f_fastlocals;
+	map = f->f_localmap;
+	if (locals == NULL || fast == NULL || map == NULL)
+		return locals;
+	if (!is_dictobject(locals) || !is_listobject(fast) ||
+	    !is_dictobject(map))
+		return locals;
+	i = getdictsize(map);
+	while (--i >= 0) {
+		object *key;
+		object *value;
+		int j;
+		key = getdict2key(map, i);
+		if (key == NULL)
+			continue;
+		value = dict2lookup(map, key);
+		if (value == NULL || !is_intobject(value))
+			continue;
+		j = getintvalue(value);
+		value = getlistitem(fast, j);
+		if (value == NULL) {
+			err_clear();
+			if (dict2remove(locals, key) != 0)
+				err_clear();
+		}
+		else {
+			if (dict2insert(locals, key, value) != 0)
+				err_clear();
+		}
+	}
+	return locals;
+}
+
+static void
+locals_2_fast(f, clear)
+	frameobject *f;
+	int clear;
+{
+	/* Merge f->f_locals into f->f_fastlocals */
+	object *locals, *fast, *map;
+	int i;
+	if (f == NULL)
+		return;
+	locals = f->f_locals;
+	fast = f->f_fastlocals;
+	map = f->f_localmap;
+	if (locals == NULL || fast == NULL || map == NULL)
+		return;
+	if (!is_dictobject(locals) || !is_listobject(fast) ||
+	    !is_dictobject(map))
+		return;
+	i = getdictsize(map);
+	while (--i >= 0) {
+		object *key;
+		object *value;
+		int j;
+		key = getdict2key(map, i);
+		if (key == NULL)
+			continue;
+		value = dict2lookup(map, key);
+		if (value == NULL || !is_intobject(value))
+			continue;
+		j = getintvalue(value);
+		value = dict2lookup(locals, key);
+		if (value == NULL)
+			err_clear();
+		else
+			INCREF(value);
+		if (value != NULL || clear)
+			if (setlistitem(fast, j, value) != 0)
+				err_clear();
+	}
+}
+
+void
+mergelocals()
+{
+	locals_2_fast(current_frame, 1);
 }
 
 object *