blob: bc0aeed295854e1adf3325d903edae90fb37d488 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum9bfef441993-03-29 10:43:31 +00002Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
3Amsterdam, The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
Guido van Rossum3f5da241990-12-20 15:06:42 +000025/* Generic object operations; and implementation of None (NoObject) */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000026
Guido van Rossum3f5da241990-12-20 15:06:42 +000027#include "allobjects.h"
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000028
Guido van Rossum3f5da241990-12-20 15:06:42 +000029#ifdef REF_DEBUG
30long ref_total;
31#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032
Guido van Rossum3f5da241990-12-20 15:06:42 +000033/* Object allocation routines used by NEWOBJ and NEWVAROBJ macros.
34 These are used by the individual routines for object creation.
35 Do not call them otherwise, they do not initialize the object! */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000036
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000037#ifdef COUNT_ALLOCS
38static typeobject *type_list;
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000039extern int tuple_zero_allocs, fast_tuple_allocs;
40extern int quick_int_allocs, quick_neg_int_allocs;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000041void
42dump_counts()
43{
44 typeobject *tp;
45
46 for (tp = type_list; tp; tp = tp->tp_next)
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000047 printf("%s alloc'd: %d, freed: %d, max in use: %d\n",
48 tp->tp_name, tp->tp_alloc, tp->tp_free,
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000049 tp->tp_maxalloc);
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000050 printf("fast tuple allocs: %d, empty: %d\n", fast_tuple_allocs,
51 tuple_zero_allocs);
52 printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs,
53 quick_neg_int_allocs);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000054}
55
56void
57inc_count(tp)
58 typeobject *tp;
59{
60 if (tp->tp_alloc == 0) {
61 /* first time; hang in linked list */
62 if (tp->tp_next != NULL) /* sanity check */
63 abort();
64 tp->tp_next = type_list;
65 type_list = tp;
66 }
67 tp->tp_alloc++;
68 if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
69 tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
70}
71#endif
72
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000073object *
74newobject(tp)
75 typeobject *tp;
76{
77 object *op = (object *) malloc(tp->tp_basicsize);
78 if (op == NULL)
79 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000080 op->ob_type = tp;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000081 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 return op;
83}
84
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085varobject *
86newvarobject(tp, size)
87 typeobject *tp;
88 unsigned int size;
89{
90 varobject *op = (varobject *)
91 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
92 if (op == NULL)
Guido van Rossum05ab1111991-05-05 20:10:41 +000093 return (varobject *)err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000094 op->ob_type = tp;
95 op->ob_size = size;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000096 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 return op;
98}
99
Guido van Rossum90933611991-06-07 16:10:43 +0000100int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000101printobject(op, fp, flags)
102 object *op;
103 FILE *fp;
104 int flags;
105{
Guido van Rossum278ef591991-07-27 21:40:24 +0000106 int ret = 0;
Guido van Rossum90933611991-06-07 16:10:43 +0000107 if (intrcheck()) {
108 err_set(KeyboardInterrupt);
109 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000110 }
Guido van Rossum90933611991-06-07 16:10:43 +0000111 if (op == NULL) {
112 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 }
Guido van Rossum90933611991-06-07 16:10:43 +0000114 else {
115 if (op->ob_refcnt <= 0)
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000116 fprintf(fp, "<refcnt %u at %lx>",
117 op->ob_refcnt, (long)op);
118 else if (op->ob_type->tp_print == NULL) {
119 if (op->ob_type->tp_repr == NULL) {
120 fprintf(fp, "<%s object at %lx>",
121 op->ob_type->tp_name, (long)op);
122 }
123 else {
124 object *s = reprobject(op);
125 if (s == NULL)
126 ret = -1;
127 else if (!is_stringobject(s)) {
128 err_setstr(TypeError,
129 "repr not string");
130 ret = -1;
131 }
132 else {
133 fprintf(fp, "%s", getstringvalue(s));
134 }
135 XDECREF(s);
136 }
137 }
Guido van Rossum90933611991-06-07 16:10:43 +0000138 else
Guido van Rossum278ef591991-07-27 21:40:24 +0000139 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +0000140 }
Guido van Rossum278ef591991-07-27 21:40:24 +0000141 if (ret == 0) {
142 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +0000143 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +0000144 clearerr(fp);
145 ret = -1;
146 }
147 }
148 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000149}
150
151object *
152reprobject(v)
153 object *v;
154{
Guido van Rossum90933611991-06-07 16:10:43 +0000155 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000157 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 }
Guido van Rossum90933611991-06-07 16:10:43 +0000159 if (v == NULL)
160 return newstringobject("<NULL>");
161 else if (v->ob_type->tp_repr == NULL) {
162 char buf[120];
163 sprintf(buf, "<%.80s object at %lx>",
164 v->ob_type->tp_name, (long)v);
165 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000166 }
Guido van Rossum90933611991-06-07 16:10:43 +0000167 else
168 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169}
170
171int
172cmpobject(v, w)
173 object *v, *w;
174{
175 typeobject *tp;
176 if (v == w)
177 return 0;
178 if (v == NULL)
179 return -1;
180 if (w == NULL)
181 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000182 if ((tp = v->ob_type) != w->ob_type) {
183 if (tp->tp_as_number != NULL &&
184 w->ob_type->tp_as_number != NULL) {
185 if (coerce(&v, &w) != 0) {
186 err_clear();
187 /* XXX Should report the error,
188 XXX but the interface isn't there... */
189 }
190 else {
191 int cmp = (*v->ob_type->tp_compare)(v, w);
192 DECREF(v);
193 DECREF(w);
194 return cmp;
195 }
196 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000197 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000198 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 if (tp->tp_compare == NULL)
200 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000201 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202}
203
Guido van Rossum9bfef441993-03-29 10:43:31 +0000204long
205hashobject(v)
206 object *v;
207{
208 typeobject *tp = v->ob_type;
209 if (tp->tp_hash != NULL)
210 return (*tp->tp_hash)(v);
211 if (tp->tp_compare == NULL)
212 return (long) v; /* Use address as hash value */
213 /* If there's a cmp but no hash defined, the object can't be hashed */
214 err_setstr(TypeError, "unhashable type");
215 return -1;
216}
217
Guido van Rossum3f5da241990-12-20 15:06:42 +0000218object *
219getattr(v, name)
220 object *v;
221 char *name;
222{
223 if (v->ob_type->tp_getattr == NULL) {
224 err_setstr(TypeError, "attribute-less object");
225 return NULL;
226 }
227 else {
228 return (*v->ob_type->tp_getattr)(v, name);
229 }
230}
231
232int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000233hasattr(v, name)
234 object *v;
235 char *name;
236{
237 object *res = getattr(v, name);
238 if (res != NULL) {
239 DECREF(res);
240 return 1;
241 }
242 err_clear();
243 return 0;
244}
245
246int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000247setattr(v, name, w)
248 object *v;
249 char *name;
250 object *w;
251{
252 if (v->ob_type->tp_setattr == NULL) {
253 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000254 err_setstr(TypeError,
255 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000256 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000257 err_setstr(TypeError,
258 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000259 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000260 }
261 else {
262 return (*v->ob_type->tp_setattr)(v, name, w);
263 }
264}
265
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000266/* Test a value used as condition, e.g., in a for or if statement.
267 Return -1 if an error occurred */
268
269int
270testbool(v)
271 object *v;
272{
273 int res;
274 if (v == None)
275 res = 0;
276 else if (v->ob_type->tp_as_number != NULL)
277 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
278 else if (v->ob_type->tp_as_mapping != NULL)
279 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
280 else if (v->ob_type->tp_as_sequence != NULL)
281 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
282 else
283 res = 1;
284 if (res > 0)
285 res = 1;
286 return res;
287}
288
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000289
290/*
291NoObject is usable as a non-NULL undefined value, used by the macro None.
292There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000293so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000294*/
295
Guido van Rossum0c182a11992-03-27 17:26:13 +0000296/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000297static object *
298none_repr(op)
299 object *op;
300{
301 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302}
303
304static typeobject Notype = {
305 OB_HEAD_INIT(&Typetype)
306 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000307 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000308 0,
309 0,
310 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000311 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000312 0, /*tp_getattr*/
313 0, /*tp_setattr*/
314 0, /*tp_compare*/
315 none_repr, /*tp_repr*/
316 0, /*tp_as_number*/
317 0, /*tp_as_sequence*/
318 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000319 0, /*tp_hash */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000320};
321
322object NoObject = {
323 OB_HEAD_INIT(&Notype)
324};
325
326
327#ifdef TRACE_REFS
328
329static object refchain = {&refchain, &refchain};
330
331NEWREF(op)
332 object *op;
333{
334 ref_total++;
335 op->ob_refcnt = 1;
336 op->_ob_next = refchain._ob_next;
337 op->_ob_prev = &refchain;
338 refchain._ob_next->_ob_prev = op;
339 refchain._ob_next = op;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000340#ifdef COUNT_ALLOCS
341 inc_count(op->ob_type);
342#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000343}
344
Guido van Rossum3f5da241990-12-20 15:06:42 +0000345UNREF(op)
346 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000347{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000348 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000349 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000350 fprintf(stderr, "UNREF negative refcnt\n");
351 abort();
352 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000353 if (op == &refchain ||
354 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
355 fprintf(stderr, "UNREF invalid object\n");
356 abort();
357 }
358#ifdef SLOW_UNREF_CHECK
Guido van Rossum3f5da241990-12-20 15:06:42 +0000359 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
360 if (p == op)
361 break;
362 }
363 if (p == &refchain) { /* Not found */
364 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000365 abort();
366 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000367#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000368 op->_ob_next->_ob_prev = op->_ob_prev;
369 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000370 op->_ob_next = op->_ob_prev = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000371}
372
373DELREF(op)
374 object *op;
375{
376 UNREF(op);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000377#ifdef COUNT_ALLOCS
378 op->ob_type->tp_free++;
379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380 (*(op)->ob_type->tp_dealloc)(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000381 op->ob_type = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000382}
383
384printrefs(fp)
385 FILE *fp;
386{
387 object *op;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000388 fprintf(fp, "Remaining objects (except strings referenced once):\n");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000390 if (op->ob_refcnt == 1 && is_stringobject(op))
391 continue; /* Will be printed elsewhere */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000393 if (printobject(op, fp, 0) != 0)
394 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 putc('\n', fp);
396 }
397}
398
399#endif