changes for keyword arguments and fast function call; added abstract.c
diff --git a/Objects/Makefile.in b/Objects/Makefile.in
index 60a71ca..cdf4852 100644
--- a/Objects/Makefile.in
+++ b/Objects/Makefile.in
@@ -26,14 +26,14 @@
 
 # === Fixed definitions ===
 
-OBJS=		accessobject.o \
+OBJS=		abstract.o accessobject.o \
 		classobject.o fileobject.o floatobject.o \
 		frameobject.o funcobject.o intobject.o listobject.o \
 		longobject.o mappingobject.o methodobject.o \
 		moduleobject.o object.o rangeobject.o stringobject.o \
 		tupleobject.o typeobject.o
 
-SRCS=		accessobject.c \
+SRCS=		abstract.c accessobject.c \
 		classobject.c fileobject.c floatobject.c \
 		frameobject.c funcobject.c intobject.c listobject.c \
 		longobject.c mappingobject.c methodobject.c \
@@ -68,6 +68,7 @@
 
 .PRECIOUS:	Makefile
 
+abstract.o: abstract.c
 accessobject.o: accessobject.c
 classobject.o: classobject.c
 fileobject.o: fileobject.c
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index db02924..b288408 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -44,7 +44,6 @@
 #if 0
 	{"f_fastlocals",T_OBJECT,	OFF(f_fastlocals),RO}, /* XXX Unsafe */
 #endif
-	{"f_localmap",	T_OBJECT,	OFF(f_localmap),RO},
 	{"f_lasti",	T_INT,		OFF(f_lasti),	RO},
 	{"f_lineno",	T_INT,		OFF(f_lineno),	RO},
 	{"f_restricted",T_INT,		OFF(f_restricted),RO},
@@ -105,7 +104,6 @@
 	XDECREF(f->f_locals);
 	XDECREF(f->f_owner);
 	XDECREF(f->f_fastlocals);
-	XDECREF(f->f_localmap);
 	XDECREF(f->f_trace);
 	f->f_back = free_list;
 	free_list = f;
@@ -149,7 +147,7 @@
 	if ((back != NULL && !is_frameobject(back)) ||
 		code == NULL || !is_codeobject(code) ||
 		globals == NULL || !is_dictobject(globals) ||
-		locals == NULL || !is_dictobject(locals) ||
+		locals != NULL && !is_dictobject(locals) ||
 		nvalues < 0 || nblocks < 0) {
 		err_badcall();
 		return NULL;
@@ -163,6 +161,8 @@
 	}
 	if (free_list == NULL) {
 		f = NEWOBJ(frameobject, &Frametype);
+		if (f == NULL)
+			return NULL;
 		f->f_nvalues = f->f_nblocks = 0;
 		f->f_valuestack = NULL;
 		f->f_blockstack = NULL;
@@ -173,42 +173,57 @@
 		f->ob_type = &Frametype;
 		NEWREF(f);
 	}
-	if (f != NULL) {
-		XINCREF(back);
-		f->f_back = back;
-		INCREF(code);
-		f->f_code = code;
-		XINCREF(builtins);
-		f->f_builtins = builtins;
-		INCREF(globals);
-		f->f_globals = globals;
-		INCREF(locals);
-		f->f_locals = locals;
-		XINCREF(owner);
-		f->f_owner = owner;
-		f->f_fastlocals = NULL;
-		f->f_localmap = NULL;
-		if (nvalues > f->f_nvalues || f->f_valuestack == NULL) {
-			XDEL(f->f_valuestack);
-			f->f_valuestack = NEW(object *, nvalues+1);
-			f->f_nvalues = nvalues;
-		}
-		if (nblocks > f->f_nblocks || f->f_blockstack == NULL) {
-			XDEL(f->f_blockstack);
-			f->f_blockstack = NEW(block, nblocks+1);
-			f->f_nblocks = nblocks;
-		}
-		f->f_iblock = 0;
-		f->f_lasti = 0;
-		f->f_lineno = -1;
-		f->f_restricted = (builtins != getbuiltindict());
-		f->f_trace = NULL;
-		if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
-			err_nomem();
+	XINCREF(back);
+	f->f_back = back;
+	INCREF(code);
+	f->f_code = code;
+	XINCREF(builtins);
+	f->f_builtins = builtins;
+	INCREF(globals);
+	f->f_globals = globals;
+	if ((code->co_flags & (CO_NEWLOCALS|CO_OPTIMIZED)) == CO_NEWLOCALS) {
+		locals = newdictobject();
+		if (locals == NULL) {
 			DECREF(f);
-			f = NULL;
+			return NULL;
 		}
 	}
+	else {
+		if (locals == NULL)
+			locals = globals;
+		INCREF(locals);
+	}
+	f->f_locals = locals;
+	XINCREF(owner);
+	f->f_owner = owner;
+	f->f_fastlocals = NULL;
+	if (code->co_nlocals > 0) {
+		f->f_fastlocals = newlistobject(code->co_nlocals);
+		if (f->f_fastlocals == NULL) {
+			DECREF(f);
+			return NULL;
+		}
+	}
+	if (nvalues > f->f_nvalues || f->f_valuestack == NULL) {
+		XDEL(f->f_valuestack);
+		f->f_valuestack = NEW(object *, nvalues+1);
+		f->f_nvalues = nvalues;
+	}
+	if (nblocks > f->f_nblocks || f->f_blockstack == NULL) {
+		XDEL(f->f_blockstack);
+		f->f_blockstack = NEW(block, nblocks+1);
+		f->f_nblocks = nblocks;
+	}
+	f->f_iblock = 0;
+	f->f_lasti = 0;
+	f->f_lineno = -1;
+	f->f_restricted = (builtins != getbuiltindict());
+	f->f_trace = NULL;
+	if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
+		err_nomem();
+		DECREF(f);
+		return NULL;
+	}
 	return f;
 }
 
@@ -270,11 +285,18 @@
 	int j;
 	if (f == NULL)
 		return;
-	locals = f->f_locals;
 	fast = f->f_fastlocals;
-	map = f->f_localmap;
-	if (locals == NULL || fast == NULL || map == NULL)
+	if (fast == NULL || f->f_code->co_nlocals == 0)
 		return;
+	map = f->f_code->co_varnames;
+	locals = f->f_locals;
+	if (locals == NULL) {
+		locals = f->f_locals = newdictobject();
+		if (locals == NULL) {
+			err_clear(); /* Can't report it :-( */
+			return;
+		}
+	}
 	if (!is_dictobject(locals) || !is_listobject(fast) ||
 	    !is_tupleobject(map))
 		return;
@@ -308,8 +330,8 @@
 		return;
 	locals = f->f_locals;
 	fast = f->f_fastlocals;
-	map = f->f_localmap;
-	if (locals == NULL || fast == NULL || map == NULL)
+	map = f->f_code->co_varnames;
+	if (locals == NULL || fast == NULL || f->f_code->co_nlocals == 0)
 		return;
 	if (!is_dictobject(locals) || !is_listobject(fast) ||
 	    !is_tupleobject(map))
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index dcceb72..f6ec71e 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -43,8 +43,7 @@
 		op->func_globals = globals;
 		op->func_name = ((codeobject *)code)->co_name;
 		INCREF(op->func_name);
-		op->func_argcount = -1; /* Unknown */
-		op->func_argdefs = NULL; /* No default arguments */
+		op->func_defaults = NULL; /* No default arguments */
 		consts = ((codeobject *)code)->co_consts;
 		if (gettuplesize(consts) >= 1) {
 			doc = gettupleitem(consts, 0);
@@ -82,40 +81,35 @@
 }
 
 object *
-getfuncargstuff(op, argcount_return)
+PyFunction_GetDefaults(op)
 	object *op;
-	int *argcount_return;
 {
 	if (!is_funcobject(op)) {
 		err_badcall();
 		return NULL;
 	}
-	*argcount_return = ((funcobject *) op) -> func_argcount;
-	return ((funcobject *) op) -> func_argdefs;
+	return ((funcobject *) op) -> func_defaults;
 }
 
 int
-setfuncargstuff(op, argcount, argdefs)
+PyFunction_SetDefaults(op, defaults)
 	object *op;
-	int argcount;
-	object *argdefs;
+	object *defaults;
 {
-	if (!is_funcobject(op) ||
-	    argdefs != NULL && !is_tupleobject(argdefs)) {
+	if (!is_funcobject(op)) {
 		err_badcall();
 		return -1;
 	}
-	if (argdefs == None)
-		argdefs = NULL;
-	else if (is_tupleobject(argdefs))
-		XINCREF(argdefs);
+	if (defaults == None)
+		defaults = NULL;
+	else if (is_tupleobject(defaults))
+		XINCREF(defaults);
 	else {
 		err_setstr(SystemError, "non-tuple default args");
 		return -1;
 	}
-	((funcobject *) op) -> func_argcount = argcount;
-	XDECREF(((funcobject *) op) -> func_argdefs);
-	((funcobject *) op) -> func_argdefs = argdefs;
+	XDECREF(((funcobject *) op) -> func_defaults);
+	((funcobject *) op) -> func_defaults = defaults;
 	return 0;
 }
 
@@ -128,8 +122,7 @@
 	{"func_globals",T_OBJECT,	OFF(func_globals),	READONLY},
 	{"func_name",	T_OBJECT,	OFF(func_name),		READONLY},
 	{"__name__",	T_OBJECT,	OFF(func_name),		READONLY},
-	{"func_argcount",T_INT,		OFF(func_argcount),	READONLY},
-	{"func_argdefs",T_OBJECT,	OFF(func_argdefs),	READONLY},
+	{"func_defaults",T_OBJECT,	OFF(func_defaults),	READONLY},
 	{"func_doc",	T_OBJECT,	OFF(func_doc)},
 	{"__doc__",	T_OBJECT,	OFF(func_doc)},
 	{NULL}	/* Sentinel */
@@ -155,7 +148,7 @@
 	DECREF(op->func_code);
 	DECREF(op->func_globals);
 	DECREF(op->func_name);
-	XDECREF(op->func_argdefs);
+	XDECREF(op->func_defaults);
 	XDECREF(op->func_doc);
 	DEL(op);
 }
@@ -181,10 +174,7 @@
 	int c;
 	if (f->func_globals != g->func_globals)
 		return (f->func_globals < g->func_globals) ? -1 : 1;
-	c = f->func_argcount < g->func_argcount;
-	if (c != 0)
-		return c < 0 ? -1 : 1;
-	c = cmpobject(f->func_argdefs, g->func_argdefs);
+	c = cmpobject(f->func_defaults, g->func_defaults);
 	if (c != 0)
 		return c;
 	return cmpobject(f->func_code, g->func_code);