| Guido van Rossum | f70e43a | 1991-02-19 12:39:46 +0000 | [diff] [blame] | 1 | /*********************************************************** | 
| Guido van Rossum | 8dd79cf | 1992-04-05 14:24:32 +0000 | [diff] [blame] | 2 | Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The | 
| Guido van Rossum | f70e43a | 1991-02-19 12:39:46 +0000 | [diff] [blame] | 3 | Netherlands. | 
 | 4 |  | 
 | 5 |                         All Rights Reserved | 
 | 6 |  | 
 | 7 | Permission to use, copy, modify, and distribute this software and its  | 
 | 8 | documentation for any purpose and without fee is hereby granted,  | 
 | 9 | provided that the above copyright notice appear in all copies and that | 
 | 10 | both that copyright notice and this permission notice appear in  | 
 | 11 | supporting documentation, and that the names of Stichting Mathematisch | 
 | 12 | Centrum or CWI not be used in advertising or publicity pertaining to | 
 | 13 | distribution of the software without specific, written prior permission. | 
 | 14 |  | 
 | 15 | STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO | 
 | 16 | THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND | 
 | 17 | FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE | 
 | 18 | FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | 
 | 19 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 
 | 20 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | 
 | 21 | OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 
 | 22 |  | 
 | 23 | ******************************************************************/ | 
 | 24 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 25 | /* Class object implementation */ | 
 | 26 |  | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 27 | #include "allobjects.h" | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 28 | #include "modsupport.h" | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 29 | #include "structmember.h" | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 30 | #include "ceval.h" | 
 | 31 |  | 
 | 32 | extern typeobject MappingInstancetype; | 
 | 33 | extern typeobject SequenceInstancetype; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 34 |  | 
 | 35 | typedef struct { | 
 | 36 | 	OB_HEAD | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 37 | 	object	*cl_bases;	/* A tuple */ | 
 | 38 | 	object	*cl_methods;	/* A dictionary */ | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 39 | 	object	*cl_name;	/* A string */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 40 | } classobject; | 
 | 41 |  | 
 | 42 | object * | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 43 | newclassobject(bases, methods, name) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 44 | 	object *bases; /* NULL or tuple of classobjects! */ | 
 | 45 | 	object *methods; | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 46 | 	object *name; /* String; NULL if unknown */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 47 | { | 
 | 48 | 	classobject *op; | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 49 | 	if (bases == NULL) { | 
 | 50 | 		bases = newtupleobject(0); | 
 | 51 | 		if (bases == NULL) | 
 | 52 | 			return err_nomem(); | 
 | 53 | 	} | 
 | 54 | 	else | 
 | 55 | 		INCREF(bases); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 56 | 	op = NEWOBJ(classobject, &Classtype); | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 57 | 	if (op == NULL) { | 
 | 58 | 		DECREF(bases); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 59 | 		return NULL; | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 60 | 	} | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 61 | 	op->cl_bases = bases; | 
 | 62 | 	INCREF(methods); | 
 | 63 | 	op->cl_methods = methods; | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 64 | 	XINCREF(name); | 
 | 65 | 	op->cl_name = name; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 66 | 	return (object *) op; | 
 | 67 | } | 
 | 68 |  | 
 | 69 | /* Class methods */ | 
 | 70 |  | 
 | 71 | static void | 
 | 72 | class_dealloc(op) | 
 | 73 | 	classobject *op; | 
 | 74 | { | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 75 | 	DECREF(op->cl_bases); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 76 | 	DECREF(op->cl_methods); | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 77 | 	XDECREF(op->cl_name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 78 | 	free((ANY *)op); | 
 | 79 | } | 
 | 80 |  | 
 | 81 | static object * | 
 | 82 | class_getattr(op, name) | 
 | 83 | 	register classobject *op; | 
 | 84 | 	register char *name; | 
 | 85 | { | 
 | 86 | 	register object *v; | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 87 | 	if (strcmp(name, "__dict__") == 0) { | 
 | 88 | 		INCREF(op->cl_methods); | 
 | 89 | 		return op->cl_methods; | 
 | 90 | 	} | 
 | 91 | 	if (strcmp(name, "__bases__") == 0) { | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 92 | 		INCREF(op->cl_bases); | 
 | 93 | 		return op->cl_bases; | 
 | 94 | 	} | 
 | 95 | 	if (strcmp(name, "__name__") == 0) { | 
 | 96 | 		if (op->cl_name == NULL) | 
 | 97 | 			v = None; | 
 | 98 | 		else | 
 | 99 | 			v = op->cl_name; | 
 | 100 | 		INCREF(v); | 
 | 101 | 		return v; | 
 | 102 | 	} | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 103 | 	v = dictlookup(op->cl_methods, name); | 
 | 104 | 	if (v != NULL) { | 
 | 105 | 		INCREF(v); | 
 | 106 | 		return v; | 
 | 107 | 	} | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 108 | 	{ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 109 | 		int n = gettuplesize(op->cl_bases); | 
 | 110 | 		int i; | 
 | 111 | 		for (i = 0; i < n; i++) { | 
| Guido van Rossum | 85998fa | 1992-03-27 17:23:48 +0000 | [diff] [blame] | 112 | 			v = class_getattr((classobject *) | 
| Guido van Rossum | 8dd79cf | 1992-04-05 14:24:32 +0000 | [diff] [blame] | 113 | 					gettupleitem(op->cl_bases, i), name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 114 | 			if (v != NULL) | 
 | 115 | 				return v; | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 116 | 			err_clear(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 117 | 		} | 
 | 118 | 	} | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 119 | 	err_setstr(AttributeError, name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 120 | 	return NULL; | 
 | 121 | } | 
 | 122 |  | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 123 | static int | 
 | 124 | class_setattr(op, name, v) | 
 | 125 | 	classobject *op; | 
 | 126 | 	char *name; | 
 | 127 | 	object *v; | 
 | 128 | { | 
| Guido van Rossum | 8dd79cf | 1992-04-05 14:24:32 +0000 | [diff] [blame] | 129 | 	if (name[0] == '_' && name[1] == '_') { | 
 | 130 | 		int n = strlen(name); | 
 | 131 | 		if (name[n-1] == '_' && name[n-2] == '_') { | 
 | 132 | 			err_setstr(TypeError, "read-only special attribute"); | 
 | 133 | 			return -1; | 
 | 134 | 		} | 
 | 135 | 	} | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 136 | 	if (v == NULL) | 
 | 137 | 		return dictremove(op->cl_methods, name); | 
 | 138 | 	else | 
 | 139 | 		return dictinsert(op->cl_methods, name, v); | 
 | 140 | } | 
 | 141 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 142 | typeobject Classtype = { | 
 | 143 | 	OB_HEAD_INIT(&Typetype) | 
 | 144 | 	0, | 
 | 145 | 	"class", | 
 | 146 | 	sizeof(classobject), | 
 | 147 | 	0, | 
 | 148 | 	class_dealloc,	/*tp_dealloc*/ | 
 | 149 | 	0,		/*tp_print*/ | 
 | 150 | 	class_getattr,	/*tp_getattr*/ | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 151 | 	class_setattr,	/*tp_setattr*/ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 152 | 	0,		/*tp_compare*/ | 
 | 153 | 	0,		/*tp_repr*/ | 
 | 154 | 	0,		/*tp_as_number*/ | 
 | 155 | 	0,		/*tp_as_sequence*/ | 
 | 156 | 	0,		/*tp_as_mapping*/ | 
 | 157 | }; | 
 | 158 |  | 
 | 159 |  | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 160 | /* We're not done yet: next, we define instance objects... */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 161 |  | 
 | 162 | typedef struct { | 
 | 163 | 	OB_HEAD | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 164 | 	classobject	*in_class;	/* The class object */ | 
 | 165 | 	object		*in_attr;	/* A dictionary */ | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 166 | } instanceobject; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 167 |  | 
 | 168 | object * | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 169 | newinstanceobject(class) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 170 | 	register object *class; | 
 | 171 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 172 | 	register instanceobject *inst; | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 173 | 	object *v; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 174 | 	if (!is_classobject(class)) { | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 175 | 		err_badcall(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 176 | 		return NULL; | 
 | 177 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 178 | 	inst = NEWOBJ(instanceobject, &Instancetype); | 
 | 179 | 	if (inst == NULL) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 180 | 		return NULL; | 
 | 181 | 	INCREF(class); | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 182 | 	inst->in_class = (classobject *)class; | 
 | 183 | 	inst->in_attr = newdictobject(); | 
 | 184 | 	if (inst->in_attr == NULL) { | 
 | 185 | 		DECREF(inst); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 186 | 		return NULL; | 
 | 187 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 188 | 	return (object *)inst; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 189 | } | 
 | 190 |  | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 191 | /* Instance methods */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 192 |  | 
 | 193 | static void | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 194 | instance_dealloc(inst) | 
 | 195 | 	register instanceobject *inst; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 196 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 197 | 	DECREF(inst->in_class); | 
 | 198 | 	if (inst->in_attr != NULL) | 
 | 199 | 		DECREF(inst->in_attr); | 
 | 200 | 	free((ANY *)inst); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 201 | } | 
 | 202 |  | 
 | 203 | static object * | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 204 | instance_getattr(inst, name) | 
 | 205 | 	register instanceobject *inst; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 206 | 	register char *name; | 
 | 207 | { | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 208 | 	register object *v; | 
 | 209 | 	if (strcmp(name, "__dict__") == 0) { | 
 | 210 | 		INCREF(inst->in_attr); | 
 | 211 | 		return inst->in_attr; | 
 | 212 | 	} | 
 | 213 | 	if (strcmp(name, "__class__") == 0) { | 
 | 214 | 		INCREF(inst->in_class); | 
 | 215 | 		return (object *)inst->in_class; | 
 | 216 | 	} | 
 | 217 | 	v = dictlookup(inst->in_attr, name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 218 | 	if (v != NULL) { | 
 | 219 | 		INCREF(v); | 
 | 220 | 		return v; | 
 | 221 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 222 | 	v = class_getattr(inst->in_class, name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 223 | 	if (v == NULL) | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 224 | 		return v; /* class_getattr() has set the error */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 225 | 	if (is_funcobject(v)) { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 226 | 		object *w = newinstancemethodobject(v, (object *)inst); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 227 | 		DECREF(v); | 
 | 228 | 		return w; | 
 | 229 | 	} | 
 | 230 | 	DECREF(v); | 
| Guido van Rossum | e2966a6 | 1991-12-10 13:53:23 +0000 | [diff] [blame] | 231 | 	err_setstr(AttributeError, name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 232 | 	return NULL; | 
 | 233 | } | 
 | 234 |  | 
 | 235 | static int | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 236 | instance_setattr(inst, name, v) | 
 | 237 | 	instanceobject *inst; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 238 | 	char *name; | 
 | 239 | 	object *v; | 
 | 240 | { | 
| Guido van Rossum | 8dd79cf | 1992-04-05 14:24:32 +0000 | [diff] [blame] | 241 | 	if (name[0] == '_' && name[1] == '_') { | 
 | 242 | 		int n = strlen(name); | 
 | 243 | 		if (name[n-1] == '_' && name[n-2] == '_') { | 
 | 244 | 			err_setstr(TypeError, "read-only special attribute"); | 
 | 245 | 			return -1; | 
 | 246 | 		} | 
 | 247 | 	} | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 248 | 	if (v == NULL) | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 249 | 		return dictremove(inst->in_attr, name); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 250 | 	else | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 251 | 		return dictinsert(inst->in_attr, name, v); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 252 | } | 
 | 253 |  | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 254 | int | 
 | 255 | instance_print(inst, fp, flags) | 
 | 256 | 	instanceobject *inst; | 
 | 257 | 	FILE *fp; | 
 | 258 | 	int flags; | 
 | 259 | { | 
 | 260 | 	object *func, *repr; | 
 | 261 | 	int ret; | 
 | 262 |  | 
 | 263 | 	func = instance_getattr(inst, "__repr__"); | 
 | 264 | 	if (func == NULL) { | 
 | 265 | 		err_clear(); | 
 | 266 | 		fprintf(fp, "<instance object at %lx>", (long)inst); | 
 | 267 | 		return 0; | 
 | 268 | 	} | 
 | 269 | 	repr = call_object(func, (object *)NULL); | 
 | 270 | 	DECREF(func); | 
 | 271 | 	if (repr == NULL) | 
 | 272 | 		return -1; | 
 | 273 | 	ret = printobject(repr, fp, flags | PRINT_RAW); | 
 | 274 | 	DECREF(repr); | 
 | 275 | 	return ret; | 
 | 276 | } | 
 | 277 |  | 
 | 278 | object * | 
 | 279 | instance_repr(inst) | 
 | 280 | 	instanceobject *inst; | 
 | 281 | { | 
 | 282 | 	object *func; | 
 | 283 | 	object *res; | 
 | 284 |  | 
 | 285 | 	func = instance_getattr(inst, "__repr__"); | 
 | 286 | 	if (func == NULL) { | 
 | 287 | 		char buf[80]; | 
 | 288 | 		err_clear(); | 
 | 289 | 		sprintf(buf, "<instance object at %lx>", (long)inst); | 
 | 290 | 		return newstringobject(buf); | 
 | 291 | 	} | 
 | 292 | 	res = call_object(func, (object *)NULL); | 
 | 293 | 	DECREF(func); | 
 | 294 | 	return res; | 
 | 295 | } | 
 | 296 |  | 
 | 297 | int | 
 | 298 | instance_compare(inst, other) | 
 | 299 | 	instanceobject *inst, *other; | 
 | 300 | { | 
 | 301 | 	object *func; | 
 | 302 | 	object *res; | 
 | 303 | 	int outcome; | 
 | 304 |  | 
 | 305 | 	func = instance_getattr(inst, "__cmp__"); | 
 | 306 | 	if (func == NULL) { | 
 | 307 | 		err_clear(); | 
 | 308 | 		if (inst < other) | 
 | 309 | 			return -1; | 
 | 310 | 		if (inst > other) | 
 | 311 | 			return 1; | 
 | 312 | 		return 0; | 
 | 313 | 	} | 
 | 314 | 	res = call_object(func, (object *)other); | 
 | 315 | 	DECREF(func); | 
 | 316 | 	if (res == NULL) { | 
 | 317 | 		err_clear(); /* XXX Should report the error, bot how...??? */ | 
 | 318 | 		return 0; | 
 | 319 | 	} | 
 | 320 | 	if (is_intobject(res)) | 
 | 321 | 		outcome = getintvalue(res); | 
 | 322 | 	else | 
 | 323 | 		outcome = 0; /* XXX Should report the error, bot how...??? */ | 
 | 324 | 	DECREF(res); | 
 | 325 | 	return outcome; | 
 | 326 | } | 
 | 327 |  | 
 | 328 | int | 
 | 329 | instance_length(inst) | 
 | 330 | 	instanceobject *inst; | 
 | 331 | { | 
 | 332 | 	object *func; | 
 | 333 | 	object *res; | 
 | 334 | 	int outcome; | 
 | 335 |  | 
 | 336 | 	func = instance_getattr(inst, "__len__"); | 
 | 337 | 	if (func == NULL) | 
 | 338 | 		return -1; | 
 | 339 | 	res = call_object(func, (object *)NULL); | 
 | 340 | 	DECREF(func); | 
 | 341 | 	if (is_intobject(res)) { | 
 | 342 | 		outcome = getintvalue(res); | 
 | 343 | 		if (outcome < 0) | 
 | 344 | 			err_setstr(ValueError, "__len__() should return >= 0"); | 
 | 345 | 	} | 
 | 346 | 	else { | 
 | 347 | 		err_setstr(TypeError, "__len__() should return an int"); | 
 | 348 | 		outcome = -1; | 
 | 349 | 	} | 
 | 350 | 	DECREF(res); | 
 | 351 | 	return outcome; | 
 | 352 | } | 
 | 353 |  | 
 | 354 | object * | 
 | 355 | instance_subscript(inst, key) | 
 | 356 | 	instanceobject *inst; | 
 | 357 | 	object *key; | 
 | 358 | { | 
 | 359 | 	object *func; | 
 | 360 | 	object *arg; | 
 | 361 | 	object *res; | 
 | 362 |  | 
 | 363 | 	func = instance_getattr(inst, "__getitem__"); | 
 | 364 | 	if (func == NULL) | 
 | 365 | 		return NULL; | 
 | 366 | 	arg = mkvalue("(O)", key); | 
 | 367 | 	if (arg == NULL) { | 
 | 368 | 		DECREF(func); | 
 | 369 | 		return NULL; | 
 | 370 | 	} | 
 | 371 | 	res = call_object(func, arg); | 
 | 372 | 	DECREF(func); | 
 | 373 | 	DECREF(arg); | 
 | 374 | 	return res; | 
 | 375 | } | 
 | 376 |  | 
 | 377 | int | 
 | 378 | instance_ass_subscript(inst, key, value) | 
 | 379 | 	instanceobject*inst; | 
 | 380 | 	object *key; | 
 | 381 | 	object *value; | 
 | 382 | { | 
 | 383 | 	object *func; | 
 | 384 | 	object *arg; | 
 | 385 | 	object *res; | 
 | 386 |  | 
 | 387 | 	if (value == NULL) | 
 | 388 | 		func = instance_getattr(inst, "__delitem__"); | 
 | 389 | 	else | 
 | 390 | 		func = instance_getattr(inst, "__setitem__"); | 
 | 391 | 	if (func == NULL) | 
 | 392 | 		return -1; | 
 | 393 | 	if (value == NULL) | 
 | 394 | 		arg = mkvalue("(O)", key); | 
 | 395 | 	else | 
 | 396 | 		arg = mkvalue("(OO)", key, value); | 
 | 397 | 	if (arg == NULL) { | 
 | 398 | 		DECREF(func); | 
 | 399 | 		return NULL; | 
 | 400 | 	} | 
 | 401 | 	res = call_object(func, arg); | 
 | 402 | 	DECREF(func); | 
 | 403 | 	DECREF(arg); | 
 | 404 | 	if (res == NULL) | 
 | 405 | 		return -1; | 
 | 406 | 	DECREF(res); | 
 | 407 | 	return 0; | 
 | 408 | } | 
 | 409 |  | 
 | 410 | mapping_methods instance_as_mapping = { | 
 | 411 | 	instance_length,	/*mp_length*/ | 
 | 412 | 	instance_subscript,	/*mp_subscript*/ | 
 | 413 | 	instance_ass_subscript,	/*mp_ass_subscript*/ | 
 | 414 | }; | 
 | 415 |  | 
 | 416 | static object * | 
 | 417 | instance_concat(inst, other) | 
 | 418 | 	instanceobject *inst, *other; | 
 | 419 | { | 
 | 420 | 	object *func, *res; | 
 | 421 |  | 
 | 422 | 	func = instance_getattr(inst, "__add__"); | 
 | 423 | 	if (func == NULL) | 
 | 424 | 		return NULL; | 
 | 425 | 	res = call_object(func, (object *)other); | 
 | 426 | 	DECREF(func); | 
 | 427 | 	return res; | 
 | 428 | } | 
 | 429 |  | 
 | 430 | static object * | 
 | 431 | instance_repeat(inst, count) | 
 | 432 | 	instanceobject *inst; | 
 | 433 | 	int count; | 
 | 434 | { | 
 | 435 | 	object *func, *arg, *res; | 
 | 436 |  | 
 | 437 | 	func = instance_getattr(inst, "__mul__"); | 
 | 438 | 	if (func == NULL) | 
 | 439 | 		return NULL; | 
 | 440 | 	arg = newintobject((long)count); | 
 | 441 | 	if (arg == NULL) { | 
 | 442 | 		DECREF(func); | 
 | 443 | 		return NULL; | 
 | 444 | 	} | 
 | 445 | 	res = call_object(func, arg); | 
 | 446 | 	DECREF(func); | 
 | 447 | 	DECREF(arg); | 
 | 448 | 	return res; | 
 | 449 | } | 
 | 450 |  | 
 | 451 | static object * | 
 | 452 | instance_item(inst, i) | 
 | 453 | 	instanceobject *inst; | 
 | 454 | 	int i; | 
 | 455 | { | 
 | 456 | 	object *func, *arg, *res; | 
 | 457 |  | 
 | 458 | 	func = instance_getattr(inst, "__getitem__"); | 
 | 459 | 	if (func == NULL) | 
 | 460 | 		return NULL; | 
 | 461 | 	arg = newintobject((long)i); | 
 | 462 | 	if (arg == NULL) { | 
 | 463 | 		DECREF(func); | 
 | 464 | 		return NULL; | 
 | 465 | 	} | 
 | 466 | 	res = call_object(func, arg); | 
 | 467 | 	DECREF(func); | 
 | 468 | 	DECREF(arg); | 
 | 469 | 	return res; | 
 | 470 | } | 
 | 471 |  | 
 | 472 | static object * | 
 | 473 | instance_slice(inst, i, j) | 
 | 474 | 	instanceobject *inst; | 
 | 475 | 	int i, j; | 
 | 476 | { | 
 | 477 | 	object *func, *arg, *res; | 
 | 478 |  | 
 | 479 | 	func = instance_getattr(inst, "__getslice__"); | 
 | 480 | 	if (func == NULL) | 
 | 481 | 		return NULL; | 
 | 482 | 	arg = mkvalue("(ii)", i, j); | 
 | 483 | 	if (arg == NULL) { | 
 | 484 | 		DECREF(func); | 
 | 485 | 		return NULL; | 
 | 486 | 	} | 
 | 487 | 	res = call_object(func, arg); | 
 | 488 | 	DECREF(func); | 
 | 489 | 	DECREF(arg); | 
 | 490 | 	return res; | 
 | 491 | } | 
 | 492 |  | 
 | 493 | static int | 
 | 494 | instance_ass_item(inst, i, item) | 
 | 495 | 	instanceobject *inst; | 
 | 496 | 	int i; | 
 | 497 | 	object *item; | 
 | 498 | { | 
 | 499 | 	object *func, *arg, *res; | 
 | 500 |  | 
 | 501 | 	if (item == NULL) | 
 | 502 | 		func = instance_getattr(inst, "__delitem__"); | 
 | 503 | 	else | 
 | 504 | 		func = instance_getattr(inst, "__setitem__"); | 
 | 505 | 	if (func == NULL) | 
 | 506 | 		return NULL; | 
 | 507 | 	if (item == NULL) | 
 | 508 | 		arg = mkvalue("i", i); | 
 | 509 | 	else | 
 | 510 | 		arg = mkvalue("(iO)", i, item); | 
 | 511 | 	if (arg == NULL) { | 
 | 512 | 		DECREF(func); | 
 | 513 | 		return NULL; | 
 | 514 | 	} | 
 | 515 | 	res = call_object(func, arg); | 
 | 516 | 	DECREF(func); | 
 | 517 | 	DECREF(arg); | 
 | 518 | 	if (res == NULL) | 
 | 519 | 		return -1; | 
 | 520 | 	DECREF(res); | 
 | 521 | 	return 0; | 
 | 522 | } | 
 | 523 |  | 
 | 524 | static int | 
 | 525 | instance_ass_slice(inst, i, j, value) | 
 | 526 | 	instanceobject *inst; | 
 | 527 | 	int i, j; | 
 | 528 | 	object *value; | 
 | 529 | { | 
 | 530 | 	object *func, *arg, *res; | 
 | 531 |  | 
 | 532 | 	if (value == NULL) | 
 | 533 | 		func = instance_getattr(inst, "__delslice__"); | 
 | 534 | 	else | 
 | 535 | 		func = instance_getattr(inst, "__setslice__"); | 
 | 536 | 	if (func == NULL) | 
 | 537 | 		return NULL; | 
 | 538 | 	if (value == NULL) | 
 | 539 | 		arg = mkvalue("(ii)", i, j); | 
 | 540 | 	else | 
 | 541 | 		arg = mkvalue("(iiO)", i, j, value); | 
 | 542 | 	if (arg == NULL) { | 
 | 543 | 		DECREF(func); | 
 | 544 | 		return NULL; | 
 | 545 | 	} | 
 | 546 | 	res = call_object(func, arg); | 
 | 547 | 	DECREF(func); | 
 | 548 | 	DECREF(arg); | 
 | 549 | 	if (res == NULL) | 
 | 550 | 		return -1; | 
 | 551 | 	DECREF(res); | 
 | 552 | 	return 0; | 
 | 553 | } | 
 | 554 |  | 
 | 555 | static sequence_methods instance_as_sequence = { | 
 | 556 | 	instance_length,	/*sq_length*/ | 
 | 557 | 	instance_concat,	/*sq_concat*/ | 
 | 558 | 	instance_repeat,	/*sq_repeat*/ | 
 | 559 | 	instance_item,		/*sq_item*/ | 
 | 560 | 	instance_slice,		/*sq_slice*/ | 
 | 561 | 	instance_ass_item,	/*sq_ass_item*/ | 
 | 562 | 	instance_ass_slice,	/*sq_ass_slice*/ | 
 | 563 | }; | 
 | 564 |  | 
 | 565 | static object * | 
 | 566 | generic_binary_op(self, other, methodname) | 
 | 567 | 	instanceobject *self; | 
 | 568 | 	object *other; | 
 | 569 | 	char *methodname; | 
 | 570 | { | 
 | 571 | 	object *func, *res; | 
 | 572 |  | 
 | 573 | 	if ((func = instance_getattr(self, methodname)) == NULL) | 
 | 574 | 		return NULL; | 
 | 575 | 	res = call_object(func, other); | 
 | 576 | 	DECREF(func); | 
 | 577 | 	return res; | 
 | 578 | } | 
 | 579 |  | 
 | 580 | static object * | 
 | 581 | generic_unary_op(self, methodname) | 
 | 582 | 	instanceobject *self; | 
 | 583 | 	char *methodname; | 
 | 584 | { | 
 | 585 | 	object *func, *res; | 
 | 586 |  | 
 | 587 | 	if ((func = instance_getattr(self, methodname)) == NULL) | 
 | 588 | 		return NULL; | 
 | 589 | 	res = call_object(func, (object *)NULL); | 
 | 590 | 	DECREF(func); | 
 | 591 | 	return res; | 
 | 592 | } | 
 | 593 |  | 
 | 594 | #define BINARY(funcname, methodname) \ | 
 | 595 | static object * funcname(self, other) instanceobject *self; object *other; { \ | 
 | 596 | 	return generic_binary_op(self, other, methodname); \ | 
 | 597 | } | 
 | 598 |  | 
 | 599 | #define UNARY(funcname, methodname) \ | 
 | 600 | static object *funcname(self) instanceobject *self; { \ | 
 | 601 | 	return generic_unary_op(self, methodname); \ | 
 | 602 | } | 
 | 603 |  | 
 | 604 | BINARY(instance_add, "__add__") | 
 | 605 | BINARY(instance_sub, "__sub__") | 
 | 606 | BINARY(instance_mul, "__mul__") | 
 | 607 | BINARY(instance_div, "__div__") | 
 | 608 | BINARY(instance_mod, "__mod__") | 
 | 609 | BINARY(instance_divmod, "__divmod__") | 
 | 610 | BINARY(instance_pow, "__pow__") | 
 | 611 | UNARY(instance_neg, "__neg__") | 
 | 612 | UNARY(instance_pos, "__pos__") | 
 | 613 | UNARY(instance_abs, "__abs__") | 
 | 614 |  | 
 | 615 | int | 
 | 616 | instance_nonzero(self) | 
 | 617 | 	instanceobject *self; | 
 | 618 | { | 
 | 619 | 	object *func, *res; | 
 | 620 | 	long outcome; | 
 | 621 |  | 
 | 622 | 	if ((func = instance_getattr(self, "__len__")) == NULL) { | 
 | 623 | 		err_clear(); | 
 | 624 | 		if ((func = instance_getattr(self, "__nonzero__")) == NULL) { | 
 | 625 | 			err_clear(); | 
 | 626 | 			/* Fall back to the default behavior: | 
 | 627 | 			   all instances are nonzero */ | 
 | 628 | 			return 1; | 
 | 629 | 		} | 
 | 630 | 	} | 
 | 631 | 	res = call_object(func, (object *)NULL); | 
 | 632 | 	DECREF(func); | 
 | 633 | 	if (res == NULL) | 
 | 634 | 		return -1; | 
 | 635 | 	if (!is_intobject(res)) { | 
 | 636 | 		DECREF(res); | 
 | 637 | 		err_setstr(TypeError, "__nonzero__ should return an int"); | 
 | 638 | 		return -1; | 
 | 639 | 	} | 
 | 640 | 	outcome = getintvalue(res); | 
 | 641 | 	DECREF(res); | 
 | 642 | 	if (outcome < 0) { | 
 | 643 | 		err_setstr(ValueError, "__nonzero__ should return >= 0"); | 
 | 644 | 		return -1; | 
 | 645 | 	} | 
 | 646 | 	return outcome > 0; | 
 | 647 | } | 
 | 648 |  | 
 | 649 | UNARY(instance_invert, "__invert__") | 
 | 650 | BINARY(instance_lshift, "__lshift__") | 
 | 651 | BINARY(instance_rshift, "__rshift__") | 
 | 652 | BINARY(instance_and, "__and__") | 
 | 653 | BINARY(instance_xor, "__xor__") | 
 | 654 | BINARY(instance_or, "__or__") | 
 | 655 |  | 
 | 656 | static number_methods instance_as_number = { | 
 | 657 | 	instance_add,		/*nb_add*/ | 
 | 658 | 	instance_sub,		/*nb_subtract*/ | 
 | 659 | 	instance_mul,		/*nb_multiply*/ | 
 | 660 | 	instance_div,		/*nb_divide*/ | 
 | 661 | 	instance_mod,		/*nb_remainder*/ | 
 | 662 | 	instance_divmod,	/*nb_divmod*/ | 
 | 663 | 	instance_pow,		/*nb_power*/ | 
 | 664 | 	instance_neg,		/*nb_negative*/ | 
 | 665 | 	instance_pos,		/*nb_positive*/ | 
 | 666 | 	instance_abs,		/*nb_absolute*/ | 
 | 667 | 	instance_nonzero,	/*nb_nonzero*/ | 
 | 668 | 	instance_invert,	/*nb_invert*/ | 
 | 669 | 	instance_lshift,	/*nb_lshift*/ | 
 | 670 | 	instance_rshift,	/*nb_rshift*/ | 
 | 671 | 	instance_and,		/*nb_and*/ | 
 | 672 | 	instance_xor,		/*nb_xor*/ | 
 | 673 | 	instance_or,		/*nb_or*/ | 
 | 674 | }; | 
 | 675 |  | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 676 | typeobject Instancetype = { | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 677 | 	OB_HEAD_INIT(&Typetype) | 
 | 678 | 	0, | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 679 | 	"instance", | 
 | 680 | 	sizeof(instanceobject), | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 681 | 	0, | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 682 | 	instance_dealloc,	/*tp_dealloc*/ | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 683 | 	instance_print,		/*tp_print*/ | 
| Guido van Rossum | 21ed88c | 1991-04-04 10:42:10 +0000 | [diff] [blame] | 684 | 	instance_getattr,	/*tp_getattr*/ | 
 | 685 | 	instance_setattr,	/*tp_setattr*/ | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 686 | 	instance_compare,	/*tp_compare*/ | 
 | 687 | 	instance_repr,		/*tp_repr*/ | 
 | 688 | 	&instance_as_number,	/*tp_as_number*/ | 
 | 689 | 	&instance_as_sequence,	/*tp_as_sequence*/ | 
 | 690 | 	&instance_as_mapping,	/*tp_as_mapping*/ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 691 | }; | 
 | 692 |  | 
| Guido van Rossum | 04691fc | 1992-08-12 15:35:34 +0000 | [diff] [blame^] | 693 | static int | 
 | 694 | one_coerce(pv, pw) | 
 | 695 | 	object **pv, **pw; | 
 | 696 | { | 
 | 697 | 	object *v = *pv; | 
 | 698 | 	object *w = *pw; | 
 | 699 | 	object *func; | 
 | 700 |  | 
 | 701 | 	if (!is_instanceobject(v)) | 
 | 702 | 		return 1; | 
 | 703 | 	func = instance_getattr((instanceobject *)v, "__coerce__"); | 
 | 704 | 	if (func == NULL) { | 
 | 705 | 		err_clear(); | 
 | 706 | 		return 1; | 
 | 707 | 	} | 
 | 708 | 	if (func != NULL) { | 
 | 709 | 		object *res = call_object(func, w); | 
 | 710 | 		int outcome; | 
 | 711 | 		if (res == NULL) | 
 | 712 | 			return -1; | 
 | 713 | 		outcome = getargs(res, "(OO)", &v, &w); | 
 | 714 | 		if (!outcome || v->ob_type != w->ob_type || | 
 | 715 | 			        v->ob_type->tp_as_number == NULL) { | 
 | 716 | 			DECREF(res); | 
 | 717 | 			err_setstr(TypeError, "bad __coerce__ result"); | 
 | 718 | 			return -1; | 
 | 719 | 		} | 
 | 720 | 		INCREF(v); | 
 | 721 | 		INCREF(w); | 
 | 722 | 		DECREF(res); | 
 | 723 | 		*pv = v; | 
 | 724 | 		*pw = w; | 
 | 725 | 		return 0; | 
 | 726 | 	} | 
 | 727 | } | 
 | 728 |  | 
 | 729 | int | 
 | 730 | instance_coerce(pv, pw) | 
 | 731 | 	object **pv, **pw; | 
 | 732 | { | 
 | 733 | 	int outcome; | 
 | 734 | 	outcome = one_coerce(pv, pw); | 
 | 735 | 	if (outcome > 0) { | 
 | 736 | 		outcome = one_coerce(pw, pv); | 
 | 737 | 		if (outcome > 0) { | 
 | 738 | 			err_setstr(TypeError, "uncoerceable instance"); | 
 | 739 | 			outcome = -1; | 
 | 740 | 		} | 
 | 741 | 	} | 
 | 742 | 	return outcome; | 
 | 743 | } | 
 | 744 |  | 
 | 745 | object * | 
 | 746 | instance_convert(inst, methodname) | 
 | 747 | 	object *inst; | 
 | 748 | 	char *methodname; | 
 | 749 | { | 
 | 750 | 	return generic_unary_op((instanceobject *)inst, methodname); | 
 | 751 | } | 
 | 752 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 753 |  | 
| Guido van Rossum | 9430839 | 1991-10-20 20:11:48 +0000 | [diff] [blame] | 754 | /* And finally, here are instance method objects */ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 755 |  | 
 | 756 | typedef struct { | 
 | 757 | 	OB_HEAD | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 758 | 	object	*im_func;	/* The method function */ | 
 | 759 | 	object	*im_self;	/* The object to which this applies */ | 
 | 760 | } instancemethodobject; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 761 |  | 
 | 762 | object * | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 763 | newinstancemethodobject(func, self) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 764 | 	object *func; | 
 | 765 | 	object *self; | 
 | 766 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 767 | 	register instancemethodobject *im; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 768 | 	if (!is_funcobject(func)) { | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 769 | 		err_badcall(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 770 | 		return NULL; | 
 | 771 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 772 | 	im = NEWOBJ(instancemethodobject, &Instancemethodtype); | 
 | 773 | 	if (im == NULL) | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 774 | 		return NULL; | 
 | 775 | 	INCREF(func); | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 776 | 	im->im_func = func; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 777 | 	INCREF(self); | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 778 | 	im->im_self = self; | 
 | 779 | 	return (object *)im; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 780 | } | 
 | 781 |  | 
 | 782 | object * | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 783 | instancemethodgetfunc(im) | 
 | 784 | 	register object *im; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 785 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 786 | 	if (!is_instancemethodobject(im)) { | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 787 | 		err_badcall(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 788 | 		return NULL; | 
 | 789 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 790 | 	return ((instancemethodobject *)im)->im_func; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 791 | } | 
 | 792 |  | 
 | 793 | object * | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 794 | instancemethodgetself(im) | 
 | 795 | 	register object *im; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 796 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 797 | 	if (!is_instancemethodobject(im)) { | 
| Guido van Rossum | 2a9096b | 1990-10-21 22:15:08 +0000 | [diff] [blame] | 798 | 		err_badcall(); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 799 | 		return NULL; | 
 | 800 | 	} | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 801 | 	return ((instancemethodobject *)im)->im_self; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 802 | } | 
 | 803 |  | 
 | 804 | /* Class method methods */ | 
 | 805 |  | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 806 | #define OFF(x) offsetof(instancemethodobject, x) | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 807 |  | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 808 | static struct memberlist instancemethod_memberlist[] = { | 
 | 809 | 	{"im_func",	T_OBJECT,	OFF(im_func)}, | 
 | 810 | 	{"im_self",	T_OBJECT,	OFF(im_self)}, | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 811 | 	{NULL}	/* Sentinel */ | 
 | 812 | }; | 
 | 813 |  | 
 | 814 | static object * | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 815 | instancemethod_getattr(im, name) | 
 | 816 | 	register instancemethodobject *im; | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 817 | 	char *name; | 
 | 818 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 819 | 	return getmember((char *)im, instancemethod_memberlist, name); | 
| Guido van Rossum | 3f5da24 | 1990-12-20 15:06:42 +0000 | [diff] [blame] | 820 | } | 
 | 821 |  | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 822 | static void | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 823 | instancemethod_dealloc(im) | 
 | 824 | 	register instancemethodobject *im; | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 825 | { | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 826 | 	DECREF(im->im_func); | 
 | 827 | 	DECREF(im->im_self); | 
 | 828 | 	free((ANY *)im); | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 829 | } | 
 | 830 |  | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 831 | typeobject Instancemethodtype = { | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 832 | 	OB_HEAD_INIT(&Typetype) | 
 | 833 | 	0, | 
| Guido van Rossum | 569fce7 | 1991-04-16 08:38:43 +0000 | [diff] [blame] | 834 | 	"instance method", | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 835 | 	sizeof(instancemethodobject), | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 836 | 	0, | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 837 | 	instancemethod_dealloc,	/*tp_dealloc*/ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 838 | 	0,			/*tp_print*/ | 
| Guido van Rossum | e8122f1 | 1991-05-05 20:03:07 +0000 | [diff] [blame] | 839 | 	instancemethod_getattr,	/*tp_getattr*/ | 
| Guido van Rossum | 85a5fbb | 1990-10-14 12:07:46 +0000 | [diff] [blame] | 840 | 	0,			/*tp_setattr*/ | 
 | 841 | 	0,			/*tp_compare*/ | 
 | 842 | 	0,			/*tp_repr*/ | 
 | 843 | 	0,			/*tp_as_number*/ | 
 | 844 | 	0,			/*tp_as_sequence*/ | 
 | 845 | 	0,			/*tp_as_mapping*/ | 
 | 846 | }; |