"Compiling" version
diff --git a/Objects/classobject.c b/Objects/classobject.c
index edc6070..4ee32d4 100644
--- a/Objects/classobject.c
+++ b/Objects/classobject.c
@@ -1,28 +1,17 @@
 /* Class object implementation */
 
-#include <stdio.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "node.h"
-#include "object.h"
-#include "stringobject.h"
-#include "tupleobject.h"
-#include "dictobject.h"
-#include "funcobject.h"
-#include "classobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include "structmember.h"
 
 typedef struct {
 	OB_HEAD
-	node	*cl_tree;	/* The entire classdef parse tree */
 	object	*cl_bases;	/* A tuple */
 	object	*cl_methods;	/* A dictionary */
 } classobject;
 
 object *
-newclassobject(tree, bases, methods)
-	node *tree;
+newclassobject(bases, methods)
 	object *bases; /* NULL or tuple of classobjects! */
 	object *methods;
 {
@@ -30,7 +19,6 @@
 	op = NEWOBJ(classobject, &Classtype);
 	if (op == NULL)
 		return NULL;
-	op->cl_tree = tree;
 	if (bases != NULL)
 		INCREF(bases);
 	op->cl_bases = bases;
@@ -70,6 +58,7 @@
 			v = class_getattr(gettupleitem(op->cl_bases, i), name);
 			if (v != NULL)
 				return v;
+			err_clear();
 		}
 	}
 	err_setstr(NameError, name);
@@ -242,6 +231,22 @@
 
 /* Class method methods */
 
+#define OFF(x) offsetof(classmethodobject, x)
+
+static struct memberlist classmethod_memberlist[] = {
+	{"cm_func",	T_OBJECT,	OFF(cm_func)},
+	{"cm_self",	T_OBJECT,	OFF(cm_self)},
+	{NULL}	/* Sentinel */
+};
+
+static object *
+classmethod_getattr(cm, name)
+	register classmethodobject *cm;
+	char *name;
+{
+	return getmember((char *)cm, classmethod_memberlist, name);
+}
+
 static void
 classmethod_dealloc(cm)
 	register classmethodobject *cm;
@@ -259,7 +264,7 @@
 	0,
 	classmethod_dealloc,	/*tp_dealloc*/
 	0,			/*tp_print*/
-	0,			/*tp_getattr*/
+	classmethod_getattr,	/*tp_getattr*/
 	0,			/*tp_setattr*/
 	0,			/*tp_compare*/
 	0,			/*tp_repr*/
diff --git a/Objects/fileobject.c b/Objects/fileobject.c
index 7eb6f5c..09690c6 100644
--- a/Objects/fileobject.c
+++ b/Objects/fileobject.c
@@ -2,19 +2,16 @@
 
 /* XXX This should become a built-in module 'io'.  It should support more
    functionality, better exception handling for invalid calls, etc.
+   (Especially reading on a write-only file or vice versa!)
    It should also cooperate with posix to support popen(), which should
    share most code but have a special close function. */
 
-#include <stdio.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "intobject.h"
-#include "fileobject.h"
-#include "methodobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include "errno.h"
+#ifndef errno
+extern int errno;
+#endif
 
 typedef struct {
 	OB_HEAD
@@ -29,7 +26,7 @@
 	object *f;
 {
 	if (!is_fileobject(f)) {
-		errno = EBADF;
+		err_badcall();
 		return NULL;
 	}
 	return ((fileobject *)f)->f_fp;
@@ -49,7 +46,6 @@
 	f->f_mode = newstringobject(mode);
 	if (f->f_name == NULL || f->f_mode == NULL) {
 		DECREF(f);
-		errno = ENOMEM;
 		return NULL;
 	}
 	f->f_fp = fp;
@@ -67,6 +63,7 @@
 		return NULL;
 	if ((f->f_fp = fopen(name, mode)) == NULL) {
 		DECREF(f);
+		err_errno(RuntimeError); /* XXX Should use another error */
 		return NULL;
 	}
 	return (object *)f;
@@ -75,7 +72,7 @@
 /* Methods */
 
 static void
-filedealloc(f)
+file_dealloc(f)
 	fileobject *f;
 {
 	if (f->f_fp != NULL)
@@ -88,7 +85,7 @@
 }
 
 static void
-fileprint(f, fp, flags)
+file_print(f, fp, flags)
 	fileobject *f;
 	FILE *fp;
 	int flags;
@@ -101,11 +98,11 @@
 }
 
 static object *
-filerepr(f)
+file_repr(f)
 	fileobject *f;
 {
 	char buf[300];
-	/* XXX This differs from fileprint if the filename contains
+	/* XXX This differs from file_print if the filename contains
 	   quotes or other funny characters. */
 	sprintf(buf, "<%s file '%.256s', mode '%.10s'>",
 		f->f_fp == NULL ? "closed" : "open",
@@ -115,12 +112,12 @@
 }
 
 static object *
-fileclose(f, args)
+file_close(f, args)
 	fileobject *f;
 	object *args;
 {
 	if (args != NULL) {
-		errno = EINVAL;
+		err_badarg();
 		return NULL;
 	}
 	if (f->f_fp != NULL) {
@@ -132,30 +129,28 @@
 }
 
 static object *
-fileread(f, args)
+file_read(f, args)
 	fileobject *f;
 	object *args;
 {
 	int n;
 	object *v;
 	if (f->f_fp == NULL) {
-		errno = EBADF;
+		err_badarg();
 		return NULL;
 	}
 	if (args == NULL || !is_intobject(args)) {
-		errno = EINVAL;
+		err_badarg();
 		return NULL;
 	}
 	n = getintvalue(args);
 	if (n < 0) {
-		errno = EDOM;
+		err_badarg();
 		return NULL;
 	}
 	v = newsizedstringobject((char *)NULL, n);
-	if (v == NULL) {
-		errno = ENOMEM;
+	if (v == NULL)
 		return NULL;
-	}
 	n = fread(getstringvalue(v), 1, n, f->f_fp);
 	/* EOF is reported as an empty string */
 	/* XXX should detect real I/O errors? */
@@ -166,14 +161,14 @@
 /* XXX Should this be unified with raw_input()? */
 
 static object *
-filereadline(f, args)
+file_readline(f, args)
 	fileobject *f;
 	object *args;
 {
 	int n;
 	object *v;
 	if (f->f_fp == NULL) {
-		errno = EBADF;
+		err_badarg();
 		return NULL;
 	}
 	if (args == NULL) {
@@ -181,21 +176,23 @@
 	}
 	else if (is_intobject(args)) {
 		n = getintvalue(args);
-		if (n < 0 || n > 0x7fff /*XXX*/ ) {
-			errno = EDOM;
+		if (n < 0) {
+			err_badarg();
 			return NULL;
 		}
 	}
 	else {
-		errno = EINVAL;
+		err_badarg();
 		return NULL;
 	}
 	v = newsizedstringobject((char *)NULL, n);
-	if (v == NULL) {
-		errno = ENOMEM;
+	if (v == NULL)
 		return NULL;
-	}
-	if (fgets(getstringvalue(v), n+1, f->f_fp) == NULL) {
+#ifndef THINK_C
+	/* XXX Think C reads n characters, others read n-1 characters... */
+	n = n+1;
+#endif
+	if (fgets(getstringvalue(v), n, f->f_fp) == NULL) {
 		/* EOF is reported as an empty string */
 		/* XXX should detect real I/O errors? */
 		n = 0;
@@ -208,17 +205,17 @@
 }
 
 static object *
-filewrite(f, args)
+file_write(f, args)
 	fileobject *f;
 	object *args;
 {
 	int n, n2;
 	if (f->f_fp == NULL) {
-		errno = EBADF;
+		err_badarg();
 		return NULL;
 	}
 	if (args == NULL || !is_stringobject(args)) {
-		errno = EINVAL;
+		err_badarg();
 		return NULL;
 	}
 	errno = 0;
@@ -226,36 +223,27 @@
 	if (n2 != n) {
 		if (errno == 0)
 			errno = EIO;
+		err_errno(RuntimeError);
 		return NULL;
 	}
 	INCREF(None);
 	return None;
 }
 
-static struct methodlist {
-	char *ml_name;
-	method ml_meth;
-} filemethods[] = {
-	{"write",	filewrite},
-	{"read",	fileread},
-	{"readline",	filereadline},
-	{"close",	fileclose},
+static struct methodlist file_methods[] = {
+	{"write",	file_write},
+	{"read",	file_read},
+	{"readline",	file_readline},
+	{"close",	file_close},
 	{NULL,		NULL}		/* sentinel */
 };
 
 static object *
-filegetattr(f, name)
+file_getattr(f, name)
 	fileobject *f;
 	char *name;
 {
-	struct methodlist *ml = filemethods;
-	for (; ml->ml_name != NULL; ml++) {
-		if (strcmp(name, ml->ml_name) == 0)
-			return newmethodobject(ml->ml_name, ml->ml_meth,
-				(object *)f);
-	}
-	err_setstr(NameError, name);
-	return NULL;
+	return findmethod(file_methods, (object *)f, name);
 }
 
 typeobject Filetype = {
@@ -264,10 +252,10 @@
 	"file",
 	sizeof(fileobject),
 	0,
-	filedealloc,	/*tp_dealloc*/
-	fileprint,	/*tp_print*/
-	filegetattr,	/*tp_getattr*/
+	file_dealloc,	/*tp_dealloc*/
+	file_print,	/*tp_print*/
+	file_getattr,	/*tp_getattr*/
 	0,		/*tp_setattr*/
 	0,		/*tp_compare*/
-	filerepr,	/*tp_repr*/
+	file_repr,	/*tp_repr*/
 };
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index c2b132e..82d4643 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -3,16 +3,10 @@
 /* XXX There should be overflow checks here, but it's hard to check
    for any kind of float exception without losing portability. */
 
-#include <stdio.h>
-#include <math.h>
-#include <ctype.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "object.h"
-#include "floatobject.h"
-#include "stringobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include <ctype.h>
+#include <math.h>
 
 #ifndef THINK_C
 extern double fmod PROTO((double, double));
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
new file mode 100644
index 0000000..6da3929
--- /dev/null
+++ b/Objects/frameobject.c
@@ -0,0 +1,132 @@
+/* Frame object implementation */
+
+#include "allobjects.h"
+
+#include "compile.h"
+#include "frameobject.h"
+#include "opcode.h"
+#include "structmember.h"
+
+#define OFF(x) offsetof(frameobject, x)
+
+static struct memberlist frame_memberlist[] = {
+	{"f_back",	T_OBJECT,	OFF(f_back)},
+	{"f_code",	T_OBJECT,	OFF(f_code)},
+	{"f_globals",	T_OBJECT,	OFF(f_globals)},
+	{"f_locals",	T_OBJECT,	OFF(f_locals)},
+	{NULL}	/* Sentinel */
+};
+
+static object *
+frame_getattr(f, name)
+	frameobject *f;
+	char *name;
+{
+	return getmember((char *)f, frame_memberlist, name);
+}
+
+static void
+frame_dealloc(f)
+	frameobject *f;
+{
+	XDECREF(f->f_back);
+	XDECREF(f->f_code);
+	XDECREF(f->f_globals);
+	XDECREF(f->f_locals);
+	XDEL(f->f_valuestack);
+	XDEL(f->f_blockstack);
+	DEL(f);
+}
+
+typeobject Frametype = {
+	OB_HEAD_INIT(&Typetype)
+	0,
+	"frame",
+	sizeof(frameobject),
+	0,
+	frame_dealloc,	/*tp_dealloc*/
+	0,		/*tp_print*/
+	frame_getattr,	/*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	0,		/*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
+};
+
+frameobject *
+newframeobject(back, code, globals, locals, nvalues, nblocks)
+	frameobject *back;
+	codeobject *code;
+	object *globals;
+	object *locals;
+	int nvalues;
+	int nblocks;
+{
+	frameobject *f;
+	if ((back != NULL && !is_frameobject(back)) ||
+		code == NULL || !is_codeobject(code) ||
+		globals == NULL || !is_dictobject(globals) ||
+		locals == NULL || !is_dictobject(locals) ||
+		nvalues < 0 || nblocks < 0) {
+		err_badcall();
+		return NULL;
+	}
+	f = NEWOBJ(frameobject, &Frametype);
+	if (f != NULL) {
+		if (back)
+			INCREF(back);
+		f->f_back = back;
+		INCREF(code);
+		f->f_code = code;
+		INCREF(globals);
+		f->f_globals = globals;
+		INCREF(locals);
+		f->f_locals = locals;
+		f->f_valuestack = NEW(object *, nvalues+1);
+		f->f_blockstack = NEW(block, nblocks+1);
+		f->f_nvalues = nvalues;
+		f->f_nblocks = nblocks;
+		f->f_iblock = 0;
+		if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
+			err_nomem();
+			DECREF(f);
+			f = NULL;
+		}
+	}
+	return f;
+}
+
+/* Block management */
+
+void
+setup_block(f, type, handler, level)
+	frameobject *f;
+	int type;
+	int handler;
+	int level;
+{
+	block *b;
+	if (f->f_iblock >= f->f_nblocks) {
+		fprintf(stderr, "XXX block stack overflow\n");
+		abort();
+	}
+	b = &f->f_blockstack[f->f_iblock++];
+	b->b_type = type;
+	b->b_level = level;
+	b->b_handler = handler;
+}
+
+block *
+pop_block(f)
+	frameobject *f;
+{
+	block *b;
+	if (f->f_iblock <= 0) {
+		fprintf(stderr, "XXX block stack underflow\n");
+		abort();
+	}
+	b = &f->f_blockstack[--f->f_iblock];
+	return b;
+}
diff --git a/Objects/funcobject.c b/Objects/funcobject.c
index 8850872..23236da 100644
--- a/Objects/funcobject.c
+++ b/Objects/funcobject.c
@@ -1,11 +1,8 @@
 /* Function object implementation */
 
-#include <stdio.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "object.h"
-#include "funcobject.h"
-#include "objimpl.h"
+#include "structmember.h"
 
 typedef struct {
 	OB_HEAD
@@ -52,8 +49,24 @@
 
 /* Methods */
 
+#define OFF(x) offsetof(funcobject, x)
+
+static struct memberlist func_memberlist[] = {
+	{"func_code",	T_OBJECT,	OFF(func_code)},
+	{"func_globals",T_OBJECT,	OFF(func_globals)},
+	{NULL}	/* Sentinel */
+};
+
+static object *
+func_getattr(op, name)
+	funcobject *op;
+	char *name;
+{
+	return getmember((char *)op, func_memberlist, name);
+}
+
 static void
-funcdealloc(op)
+func_dealloc(op)
 	funcobject *op;
 {
 	DECREF(op->func_code);
@@ -67,9 +80,9 @@
 	"function",
 	sizeof(funcobject),
 	0,
-	funcdealloc,	/*tp_dealloc*/
+	func_dealloc,	/*tp_dealloc*/
 	0,		/*tp_print*/
-	0,		/*tp_getattr*/
+	func_getattr,	/*tp_getattr*/
 	0,		/*tp_setattr*/
 	0,		/*tp_compare*/
 	0,		/*tp_repr*/
diff --git a/Objects/intobject.c b/Objects/intobject.c
index b0dd036..d70fcef 100644
--- a/Objects/intobject.c
+++ b/Objects/intobject.c
@@ -1,19 +1,14 @@
 /* Integer object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "intobject.h"
-#include "stringobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include "allobjects.h"
 
 /* Standard Booleans */
+
 intobject FalseObject = {
 	OB_HEAD_INIT(&Inttype)
 	0
 };
+
 intobject TrueObject = {
 	OB_HEAD_INIT(&Inttype)
 	1
@@ -33,21 +28,58 @@
 	return NULL;
 }
 
+/* Integers are quite normal objects, to make object handling uniform.
+   (Using odd pointers to represent integers would save much space
+   but require extra checks for this special case throughout the code.)
+   Since, a typical Python program spends much of its time allocating
+   and deallocating integers, these operations should be very fast.
+   Therefore we use a dedicated allocation scheme with a much lower
+   overhead (in space and time) than straight malloc(): a simple
+   dedicated free list, filled when necessary with memory from malloc().
+*/
+
+#define BLOCK_SIZE	1000	/* 1K less typical malloc overhead */
+#define N_INTOBJECTS	(BLOCK_SIZE / sizeof(intobject))
+
+static intobject *
+fill_free_list()
+{
+	intobject *p, *q;
+	p = NEW(intobject, N_INTOBJECTS);
+	if (p == NULL)
+		return (intobject *)err_nomem();
+	q = p + N_INTOBJECTS;
+	while (--q > p)
+		*(intobject **)q = q-1;
+	*(intobject **)q = NULL;
+	return p + N_INTOBJECTS - 1;
+}
+
+static intobject *free_list = NULL;
+
 object *
 newintobject(ival)
 	long ival;
 {
-	/* For efficiency, this code is copied from newobject() */
-	register intobject *op = (intobject *) malloc(sizeof(intobject));
-	if (op == NULL) {
-		err_nomem();
+	register intobject *v;
+	if (free_list == NULL) {
+		if ((free_list = fill_free_list()) == NULL)
+			return NULL;
 	}
-	else {
-		NEWREF(op);
-		op->ob_type = &Inttype;
-		op->ob_ival = ival;
-	}
-	return (object *) op;
+	v = free_list;
+	free_list = *(intobject **)free_list;
+	NEWREF(v);
+	v->ob_type = &Inttype;
+	v->ob_ival = ival;
+	return (object *) v;
+}
+
+static void
+int_dealloc(v)
+	intobject *v;
+{
+	*(intobject **)v = free_list;
+	free_list = v;
 }
 
 long
@@ -65,7 +97,7 @@
 /* Methods */
 
 static void
-intprint(v, fp, flags)
+int_print(v, fp, flags)
 	intobject *v;
 	FILE *fp;
 	int flags;
@@ -74,7 +106,7 @@
 }
 
 static object *
-intrepr(v)
+int_repr(v)
 	intobject *v;
 {
 	char buf[20];
@@ -83,7 +115,7 @@
 }
 
 static int
-intcompare(v, w)
+int_compare(v, w)
 	intobject *v, *w;
 {
 	register long i = v->ob_ival;
@@ -92,7 +124,7 @@
 }
 
 static object *
-intadd(v, w)
+int_add(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -110,7 +142,7 @@
 }
 
 static object *
-intsub(v, w)
+int_sub(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -128,7 +160,7 @@
 }
 
 static object *
-intmul(v, w)
+int_mul(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -147,7 +179,7 @@
 }
 
 static object *
-intdiv(v, w)
+int_div(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -161,7 +193,7 @@
 }
 
 static object *
-intrem(v, w)
+int_rem(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -175,7 +207,7 @@
 }
 
 static object *
-intpow(v, w)
+int_pow(v, w)
 	intobject *v;
 	register object *w;
 {
@@ -203,7 +235,7 @@
 }
 
 static object *
-intneg(v)
+int_neg(v)
 	intobject *v;
 {
 	register long a, x;
@@ -215,7 +247,7 @@
 }
 
 static object *
-intpos(v)
+int_pos(v)
 	intobject *v;
 {
 	INCREF(v);
@@ -223,14 +255,14 @@
 }
 
 static number_methods int_as_number = {
-	intadd,	/*tp_add*/
-	intsub,	/*tp_subtract*/
-	intmul,	/*tp_multiply*/
-	intdiv,	/*tp_divide*/
-	intrem,	/*tp_remainder*/
-	intpow,	/*tp_power*/
-	intneg,	/*tp_negate*/
-	intpos,	/*tp_plus*/
+	int_add,	/*tp_add*/
+	int_sub,	/*tp_subtract*/
+	int_mul,	/*tp_multiply*/
+	int_div,	/*tp_divide*/
+	int_rem,	/*tp_remainder*/
+	int_pow,	/*tp_power*/
+	int_neg,	/*tp_negate*/
+	int_pos,	/*tp_plus*/
 };
 
 typeobject Inttype = {
@@ -239,12 +271,12 @@
 	"int",
 	sizeof(intobject),
 	0,
-	free,		/*tp_dealloc*/
-	intprint,	/*tp_print*/
+	int_dealloc,	/*tp_dealloc*/
+	int_print,	/*tp_print*/
 	0,		/*tp_getattr*/
 	0,		/*tp_setattr*/
-	intcompare,	/*tp_compare*/
-	intrepr,	/*tp_repr*/
+	int_compare,	/*tp_compare*/
+	int_repr,	/*tp_repr*/
 	&int_as_number,	/*tp_as_number*/
 	0,		/*tp_as_sequence*/
 	0,		/*tp_as_mapping*/
diff --git a/Objects/listobject.c b/Objects/listobject.c
index 97088c5..c59604d 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -1,22 +1,6 @@
 /* List object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "intobject.h"
-#include "stringobject.h"
-#include "tupleobject.h"
-#include "methodobject.h"
-#include "listobject.h"
-#include "objimpl.h"
-#include "modsupport.h"
-#include "errors.h"
-
-typedef struct {
-	OB_VARHEAD
-	object **ob_item;
-} listobject;
+#include "allobjects.h"
 
 object *
 newlistobject(size)
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index c8b5ee0..5cc4b88 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -1,15 +1,8 @@
 /* Method object implementation */
 
-#include <stdio.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "object.h"
-#include "node.h"
-#include "stringobject.h"
-#include "methodobject.h"
-#include "objimpl.h"
 #include "token.h"
-#include "errors.h"
 
 typedef struct {
 	OB_HEAD
@@ -75,11 +68,10 @@
 	int flags;
 {
 	if (m->m_self == NULL)
-		fprintf(fp, "<%s method>", m->m_name);
+		fprintf(fp, "<built-in function '%s'>", m->m_name);
 	else
-		fprintf(fp, "<%s method of %s object at %lx>",
-			m->m_name, m->m_self->ob_type->tp_name,
-			(long)m->m_self);
+		fprintf(fp, "<built-in method '%s' of some %s object>",
+			m->m_name, m->m_self->ob_type->tp_name);
 }
 
 static object *
@@ -88,11 +80,11 @@
 {
 	char buf[200];
 	if (m->m_self == NULL)
-		sprintf(buf, "<%.80s method>", m->m_name);
+		sprintf(buf, "<built-in function '%.80s'>", m->m_name);
 	else
-		sprintf(buf, "<%.80s method of %.80s object at %lx>",
-			m->m_name, m->m_self->ob_type->tp_name,
-			(long)m->m_self);
+		sprintf(buf,
+			"<built-in method '%.80s' of some %.80s object>",
+			m->m_name, m->m_self->ob_type->tp_name);
 	return newstringobject(buf);
 }
 
@@ -112,3 +104,20 @@
 	0,		/*tp_as_sequence*/
 	0,		/*tp_as_mapping*/
 };
+
+/* Find a method in a module's method table.
+   Usually called from an object's getattr method. */
+
+object *
+findmethod(ml, op, name)
+	struct methodlist *ml;
+	object *op;
+	char *name;
+{
+	for (; ml->ml_name != NULL; ml++) {
+		if (strcmp(name, ml->ml_name) == 0)
+			return newmethodobject(ml->ml_name, ml->ml_meth, op);
+	}
+	err_setstr(NameError, name);
+	return NULL;
+}
diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c
index 22a793f..cf96a70 100644
--- a/Objects/moduleobject.c
+++ b/Objects/moduleobject.c
@@ -1,14 +1,6 @@
 /* Module object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "dictobject.h"
-#include "moduleobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include "allobjects.h"
 
 typedef struct {
 	OB_HEAD
@@ -37,31 +29,12 @@
 	object *m;
 {
 	if (!is_moduleobject(m)) {
-		err_badarg();
+		err_badcall();
 		return NULL;
 	}
 	return ((moduleobject *)m) -> md_dict;
 }
 
-int
-setmoduledict(m, v)
-	object *m;
-	object *v;
-{
-	if (!is_moduleobject(m)) {
-		err_badarg();
-		return -1;
-	}
-	if (!is_dictobject(v)) {
-		err_badarg();
-		return -1;
-	}
-	DECREF(((moduleobject *)m) -> md_dict);
-	INCREF(v);
-	((moduleobject *)m) -> md_dict = v;
-	return 0;
-}
-
 char *
 getmodulename(m)
 	object *m;
@@ -76,7 +49,7 @@
 /* Methods */
 
 static void
-moduledealloc(m)
+module_dealloc(m)
 	moduleobject *m;
 {
 	if (m->md_name != NULL)
@@ -87,33 +60,37 @@
 }
 
 static void
-moduleprint(m, fp, flags)
+module_print(m, fp, flags)
 	moduleobject *m;
 	FILE *fp;
 	int flags;
 {
-	fprintf(fp, "<module %s>", getstringvalue(m->md_name));
+	fprintf(fp, "<module '%s'>", getstringvalue(m->md_name));
 }
 
 static object *
-modulerepr(m)
+module_repr(m)
 	moduleobject *m;
 {
 	char buf[100];
-	sprintf(buf, "<module %.80s>", getstringvalue(m->md_name));
+	sprintf(buf, "<module '%.80s'>", getstringvalue(m->md_name));
 	return newstringobject(buf);
 }
 
 static object *
-modulegetattr(m, name)
+module_getattr(m, name)
 	moduleobject *m;
 	char *name;
 {
 	object *res;
-	if (strcmp(name, "__dict") == 0) {
+	if (strcmp(name, "__dict__") == 0) {
 		INCREF(m->md_dict);
 		return m->md_dict;
 	}
+	if (strcmp(name, "__name__") == 0) {
+		INCREF(m->md_name);
+		return m->md_name;
+	}
 	res = dictlookup(m->md_dict, name);
 	if (res == NULL)
 		err_setstr(NameError, name);
@@ -123,15 +100,13 @@
 }
 
 static int
-modulesetattr(m, name, v)
+module_setattr(m, name, v)
 	moduleobject *m;
 	char *name;
 	object *v;
 {
-	if (strcmp(name, "__dict") == 0) {
-		/* Can't allow assignment to __dict, it would screw up
-		   module's functions which still use the old dictionary. */
-		err_setstr(NameError, "__dict is a reserved member name");
+	if (strcmp(name, "__dict__") == 0 || strcmp(name, "__name__") == 0) {
+		err_setstr(NameError, "can't assign to reserved member name");
 		return NULL;
 	}
 	if (v == NULL)
@@ -146,10 +121,10 @@
 	"module",		/*tp_name*/
 	sizeof(moduleobject),	/*tp_size*/
 	0,			/*tp_itemsize*/
-	moduledealloc,	/*tp_dealloc*/
-	moduleprint,	/*tp_print*/
-	modulegetattr,	/*tp_getattr*/
-	modulesetattr,	/*tp_setattr*/
-	0,		/*tp_compare*/
-	modulerepr,	/*tp_repr*/
+	module_dealloc,		/*tp_dealloc*/
+	module_print,		/*tp_print*/
+	module_getattr,		/*tp_getattr*/
+	module_setattr,		/*tp_setattr*/
+	0,			/*tp_compare*/
+	module_repr,		/*tp_repr*/
 };
diff --git a/Objects/object.c b/Objects/object.c
index ebeb0f8..f2b4d1f 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -1,16 +1,14 @@
-/* Object implementation; and 'noobject' implementation */
+/* Generic object operations; and implementation of None (NoObject) */
 
-#include <stdio.h>
+#include "allobjects.h"
 
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#ifdef REF_DEBUG
+long ref_total;
+#endif
 
-int StopPrint; /* Flag to indicate printing must be stopped */
-
-/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros */
+/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
+   These are used by the individual routines for object creation.
+   Do not call them otherwise, they do not initialize the object! */
 
 object *
 newobject(tp)
@@ -43,6 +41,8 @@
 
 #endif
 
+int StopPrint; /* Flag to indicate printing must be stopped */
+
 static int prlevel;
 
 void
@@ -52,6 +52,7 @@
 	int flags;
 {
 	/* Hacks to make printing a long or recursive object interruptible */
+	/* XXX Interrupts should leave a more permanent error */
 	prlevel++;
 	if (!StopPrint && intrcheck()) {
 		fprintf(fp, "\n[print interrupted]\n");
@@ -61,12 +62,16 @@
 		if (op == NULL) {
 			fprintf(fp, "<nil>");
 		}
-		else if (op->ob_type->tp_print == NULL) {
-			fprintf(fp, "<%s object at %lx>",
-				op->ob_type->tp_name, (long)op);
-		}
 		else {
-			(*op->ob_type->tp_print)(op, fp, flags);
+			if (op->ob_refcnt <= 0)
+				fprintf(fp, "(refcnt %d):", op->ob_refcnt);
+			if (op->ob_type->tp_print == NULL) {
+				fprintf(fp, "<%s object at %lx>",
+					op->ob_type->tp_name, (long)op);
+			}
+			else {
+				(*op->ob_type->tp_print)(op, fp, flags);
+			}
 		}
 	}
 	prlevel--;
@@ -78,17 +83,16 @@
 reprobject(v)
 	object *v;
 {
-	object *w;
+	object *w = NULL;
 	/* Hacks to make converting a long or recursive object interruptible */
 	prlevel++;
 	if (!StopPrint && intrcheck()) {
 		StopPrint = 1;
-		w = NULL;
 		err_set(KeyboardInterrupt);
 	}
 	if (!StopPrint) {
 		if (v == NULL) {
-			w = newstringobject("<nil>");
+			w = newstringobject("<NULL>");
 		}
 		else if (v->ob_type->tp_repr == NULL) {
 			char buf[100];
@@ -99,6 +103,10 @@
 		else {
 			w = (*v->ob_type->tp_repr)(v);
 		}
+		if (StopPrint) {
+			XDECREF(w);
+			w = NULL;
+		}
 	}
 	prlevel--;
 	if (prlevel == 0)
@@ -124,30 +132,76 @@
 	return ((*tp->tp_compare)(v, w));
 }
 
+object *
+getattr(v, name)
+	object *v;
+	char *name;
+{
+	if (v->ob_type->tp_getattr == NULL) {
+		err_setstr(TypeError, "attribute-less object");
+		return NULL;
+	}
+	else {
+		return (*v->ob_type->tp_getattr)(v, name);
+	}
+}
+
+int
+setattr(v, name, w)
+	object *v;
+	char *name;
+	object *w;
+{
+	if (v->ob_type->tp_setattr == NULL) {
+		if (v->ob_type->tp_getattr == NULL)
+			err_setstr(TypeError, "attribute-less object");
+		else
+			err_setstr(TypeError, "object has read-only attributes");
+		return NULL;
+	}
+	else {
+		return (*v->ob_type->tp_setattr)(v, name, w);
+	}
+}
+
 
 /*
 NoObject is usable as a non-NULL undefined value, used by the macro None.
 There is (and should be!) no way to create other objects of this type,
-so there is exactly one.
+so there is exactly one (which is indestructible, by the way).
 */
 
 static void
-noprint(op, fp, flags)
+none_print(op, fp, flags)
 	object *op;
 	FILE *fp;
 	int flags;
 {
-	fprintf(fp, "<no value>");
+	fprintf(fp, "None");
+}
+
+static object *
+none_repr(op)
+	object *op;
+{
+	return newstringobject("None");
 }
 
 static typeobject Notype = {
 	OB_HEAD_INIT(&Typetype)
 	0,
-	"novalue",
+	"None",
 	0,
 	0,
 	0,		/*tp_dealloc*/ /*never called*/
-	noprint,	/*tp_print*/
+	none_print,	/*tp_print*/
+	0,		/*tp_getattr*/
+	0,		/*tp_setattr*/
+	0,		/*tp_compare*/
+	none_repr,	/*tp_repr*/
+	0,		/*tp_as_number*/
+	0,		/*tp_as_sequence*/
+	0,		/*tp_as_mapping*/
 };
 
 object NoObject = {
@@ -170,15 +224,30 @@
 	refchain._ob_next = op;
 }
 
-DELREF(op)
-	object *op;
+UNREF(op)
+	register object *op;
 {
+	register object *p;
 	if (op->ob_refcnt < 0) {
-		fprintf(stderr, "negative refcnt\n");
+		fprintf(stderr, "UNREF negative refcnt\n");
+		abort();
+	}
+	for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
+		if (p == op)
+			break;
+	}
+	if (p == &refchain) { /* Not found */
+		fprintf(stderr, "UNREF unknown object\n");
 		abort();
 	}
 	op->_ob_next->_ob_prev = op->_ob_prev;
 	op->_ob_prev->_ob_next = op->_ob_next;
+}
+
+DELREF(op)
+	object *op;
+{
+	UNREF(op);
 	(*(op)->ob_type->tp_dealloc)(op);
 }
 
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 40cd15a..1881bdf 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -1,13 +1,6 @@
 /* String object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "intobject.h"
-#include "objimpl.h"
-#include "errors.h"
+#include "allobjects.h"
 
 object *
 newsizedstringobject(str, size)
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 960d78a..89ba4e9 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -1,19 +1,6 @@
 /* Tuple object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "tupleobject.h"
-#include "intobject.h"
-#include "objimpl.h"
-#include "errors.h"
-
-typedef struct {
-	OB_VARHEAD
-	object *ob_item[1];
-} tupleobject;
+#include "allobjects.h"
 
 object *
 newtupleobject(size)
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index f7acaad..f80c518 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1,16 +1,11 @@
 /* Type object implementation */
 
-#include <stdio.h>
-
-#include "PROTO.h"
-#include "object.h"
-#include "stringobject.h"
-#include "objimpl.h"
+#include "allobjects.h"
 
 /* Type object implementation */
 
 static void
-typeprint(v, fp, flags)
+type_print(v, fp, flags)
 	typeobject *v;
 	FILE *fp;
 	int flags;
@@ -19,7 +14,7 @@
 }
 
 static object *
-typerepr(v)
+type_repr(v)
 	typeobject *v;
 {
 	char buf[100];
@@ -27,21 +22,16 @@
 	return newstringobject(buf);
 }
 
-typedef struct {
-	OB_HEAD
-	long ob_ival;
-} intobject;
-
 typeobject Typetype = {
 	OB_HEAD_INIT(&Typetype)
 	0,			/* Number of items for varobject */
 	"type",			/* Name of this type */
 	sizeof(typeobject),	/* Basic object size */
 	0,			/* Item size for varobject */
-	0,		/*tp_dealloc*/
-	typeprint,	/*tp_print*/
-	0,		/*tp_getattr*/
-	0,		/*tp_setattr*/
-	0,		/*tp_compare*/
-	typerepr,	/*tp_repr*/
+	0,			/*tp_dealloc*/
+	type_print,		/*tp_print*/
+	0,			/*tp_getattr*/
+	0,			/*tp_setattr*/
+	0,			/*tp_compare*/
+	type_repr,		/*tp_repr*/
 };