blob: f2d801bb6584b6aaf28812038000c7d13d91ed86 [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 Mullender3bb8a051993-10-22 12:04:32 +000041extern int null_strings, one_strings;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000042void
43dump_counts()
44{
45 typeobject *tp;
46
47 for (tp = type_list; tp; tp = tp->tp_next)
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000048 printf("%s alloc'd: %d, freed: %d, max in use: %d\n",
49 tp->tp_name, tp->tp_alloc, tp->tp_free,
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000050 tp->tp_maxalloc);
Sjoerd Mullender842d2cc1993-10-15 16:18:48 +000051 printf("fast tuple allocs: %d, empty: %d\n", fast_tuple_allocs,
52 tuple_zero_allocs);
53 printf("fast int allocs: pos: %d, neg: %d\n", quick_int_allocs,
54 quick_neg_int_allocs);
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +000055 printf("null strings: %d, 1-strings: %d\n", null_strings, one_strings);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000056}
57
58void
59inc_count(tp)
60 typeobject *tp;
61{
62 if (tp->tp_alloc == 0) {
63 /* first time; hang in linked list */
64 if (tp->tp_next != NULL) /* sanity check */
65 abort();
66 tp->tp_next = type_list;
67 type_list = tp;
68 }
69 tp->tp_alloc++;
70 if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
71 tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
72}
73#endif
74
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000075object *
76newobject(tp)
77 typeobject *tp;
78{
79 object *op = (object *) malloc(tp->tp_basicsize);
80 if (op == NULL)
81 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082 op->ob_type = tp;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000083 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000084 return op;
85}
86
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000087varobject *
88newvarobject(tp, size)
89 typeobject *tp;
90 unsigned int size;
91{
92 varobject *op = (varobject *)
93 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
94 if (op == NULL)
Guido van Rossum05ab1111991-05-05 20:10:41 +000095 return (varobject *)err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000096 op->ob_type = tp;
97 op->ob_size = size;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000098 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000099 return op;
100}
101
Guido van Rossum90933611991-06-07 16:10:43 +0000102int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000103printobject(op, fp, flags)
104 object *op;
105 FILE *fp;
106 int flags;
107{
Guido van Rossum278ef591991-07-27 21:40:24 +0000108 int ret = 0;
Guido van Rossum90933611991-06-07 16:10:43 +0000109 if (intrcheck()) {
110 err_set(KeyboardInterrupt);
111 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000112 }
Guido van Rossum90933611991-06-07 16:10:43 +0000113 if (op == NULL) {
114 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000115 }
Guido van Rossum90933611991-06-07 16:10:43 +0000116 else {
117 if (op->ob_refcnt <= 0)
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000118 fprintf(fp, "<refcnt %u at %lx>",
119 op->ob_refcnt, (long)op);
120 else if (op->ob_type->tp_print == NULL) {
121 if (op->ob_type->tp_repr == NULL) {
122 fprintf(fp, "<%s object at %lx>",
123 op->ob_type->tp_name, (long)op);
124 }
125 else {
126 object *s = reprobject(op);
127 if (s == NULL)
128 ret = -1;
129 else if (!is_stringobject(s)) {
130 err_setstr(TypeError,
131 "repr not string");
132 ret = -1;
133 }
134 else {
135 fprintf(fp, "%s", getstringvalue(s));
136 }
137 XDECREF(s);
138 }
139 }
Guido van Rossum90933611991-06-07 16:10:43 +0000140 else
Guido van Rossum278ef591991-07-27 21:40:24 +0000141 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +0000142 }
Guido van Rossum278ef591991-07-27 21:40:24 +0000143 if (ret == 0) {
144 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +0000145 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +0000146 clearerr(fp);
147 ret = -1;
148 }
149 }
150 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151}
152
153object *
154reprobject(v)
155 object *v;
156{
Guido van Rossum90933611991-06-07 16:10:43 +0000157 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000158 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000159 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 }
Guido van Rossum90933611991-06-07 16:10:43 +0000161 if (v == NULL)
162 return newstringobject("<NULL>");
163 else if (v->ob_type->tp_repr == NULL) {
164 char buf[120];
165 sprintf(buf, "<%.80s object at %lx>",
166 v->ob_type->tp_name, (long)v);
167 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000168 }
Guido van Rossum90933611991-06-07 16:10:43 +0000169 else
170 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000171}
172
173int
174cmpobject(v, w)
175 object *v, *w;
176{
177 typeobject *tp;
178 if (v == w)
179 return 0;
180 if (v == NULL)
181 return -1;
182 if (w == NULL)
183 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000184 if ((tp = v->ob_type) != w->ob_type) {
185 if (tp->tp_as_number != NULL &&
186 w->ob_type->tp_as_number != NULL) {
187 if (coerce(&v, &w) != 0) {
188 err_clear();
189 /* XXX Should report the error,
190 XXX but the interface isn't there... */
191 }
192 else {
193 int cmp = (*v->ob_type->tp_compare)(v, w);
194 DECREF(v);
195 DECREF(w);
196 return cmp;
197 }
198 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000199 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000200 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201 if (tp->tp_compare == NULL)
202 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000203 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204}
205
Guido van Rossum9bfef441993-03-29 10:43:31 +0000206long
207hashobject(v)
208 object *v;
209{
210 typeobject *tp = v->ob_type;
211 if (tp->tp_hash != NULL)
212 return (*tp->tp_hash)(v);
213 if (tp->tp_compare == NULL)
214 return (long) v; /* Use address as hash value */
215 /* If there's a cmp but no hash defined, the object can't be hashed */
216 err_setstr(TypeError, "unhashable type");
217 return -1;
218}
219
Guido van Rossum3f5da241990-12-20 15:06:42 +0000220object *
221getattr(v, name)
222 object *v;
223 char *name;
224{
225 if (v->ob_type->tp_getattr == NULL) {
226 err_setstr(TypeError, "attribute-less object");
227 return NULL;
228 }
229 else {
230 return (*v->ob_type->tp_getattr)(v, name);
231 }
232}
233
234int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000235hasattr(v, name)
236 object *v;
237 char *name;
238{
239 object *res = getattr(v, name);
240 if (res != NULL) {
241 DECREF(res);
242 return 1;
243 }
244 err_clear();
245 return 0;
246}
247
248int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000249setattr(v, name, w)
250 object *v;
251 char *name;
252 object *w;
253{
254 if (v->ob_type->tp_setattr == NULL) {
255 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000256 err_setstr(TypeError,
257 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000258 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000259 err_setstr(TypeError,
260 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000261 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000262 }
263 else {
264 return (*v->ob_type->tp_setattr)(v, name, w);
265 }
266}
267
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000268/* Test a value used as condition, e.g., in a for or if statement.
269 Return -1 if an error occurred */
270
271int
272testbool(v)
273 object *v;
274{
275 int res;
276 if (v == None)
277 res = 0;
278 else if (v->ob_type->tp_as_number != NULL)
279 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
280 else if (v->ob_type->tp_as_mapping != NULL)
281 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
282 else if (v->ob_type->tp_as_sequence != NULL)
283 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
284 else
285 res = 1;
286 if (res > 0)
287 res = 1;
288 return res;
289}
290
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000291
292/*
293NoObject is usable as a non-NULL undefined value, used by the macro None.
294There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000295so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296*/
297
Guido van Rossum0c182a11992-03-27 17:26:13 +0000298/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000299static object *
300none_repr(op)
301 object *op;
302{
303 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000304}
305
306static typeobject Notype = {
307 OB_HEAD_INIT(&Typetype)
308 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000309 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000310 0,
311 0,
312 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000313 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000314 0, /*tp_getattr*/
315 0, /*tp_setattr*/
316 0, /*tp_compare*/
317 none_repr, /*tp_repr*/
318 0, /*tp_as_number*/
319 0, /*tp_as_sequence*/
320 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000321 0, /*tp_hash */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000322};
323
324object NoObject = {
325 OB_HEAD_INIT(&Notype)
326};
327
328
329#ifdef TRACE_REFS
330
331static object refchain = {&refchain, &refchain};
332
333NEWREF(op)
334 object *op;
335{
336 ref_total++;
337 op->ob_refcnt = 1;
338 op->_ob_next = refchain._ob_next;
339 op->_ob_prev = &refchain;
340 refchain._ob_next->_ob_prev = op;
341 refchain._ob_next = op;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000342#ifdef COUNT_ALLOCS
343 inc_count(op->ob_type);
344#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345}
346
Guido van Rossum3f5da241990-12-20 15:06:42 +0000347UNREF(op)
348 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000349{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000350 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000351 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000352 fprintf(stderr, "UNREF negative refcnt\n");
353 abort();
354 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000355 if (op == &refchain ||
356 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
357 fprintf(stderr, "UNREF invalid object\n");
358 abort();
359 }
360#ifdef SLOW_UNREF_CHECK
Guido van Rossum3f5da241990-12-20 15:06:42 +0000361 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
362 if (p == op)
363 break;
364 }
365 if (p == &refchain) { /* Not found */
366 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000367 abort();
368 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000369#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000370 op->_ob_next->_ob_prev = op->_ob_prev;
371 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000372 op->_ob_next = op->_ob_prev = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000373}
374
375DELREF(op)
376 object *op;
377{
378 UNREF(op);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000379#ifdef COUNT_ALLOCS
380 op->ob_type->tp_free++;
381#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000382 (*(op)->ob_type->tp_dealloc)(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000383 op->ob_type = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384}
385
386printrefs(fp)
387 FILE *fp;
388{
389 object *op;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000390 fprintf(fp, "Remaining objects (except strings referenced once):\n");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000392 if (op->ob_refcnt == 1 && is_stringobject(op))
393 continue; /* Will be printed elsewhere */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000394 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000395 if (printobject(op, fp, 0) != 0)
396 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000397 putc('\n', fp);
398 }
399}
400
401#endif