blob: 73fba504595e7146e62c935b37a363c160e21196 [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 Mullender52c1f511993-10-25 08:40:52 +000048 fprintf(stderr, "%s alloc'd: %d, freed: %d, max in use: %d\n",
49 tp->tp_name, tp->tp_alloc, tp->tp_free,
50 tp->tp_maxalloc);
51 fprintf(stderr, "fast tuple allocs: %d, empty: %d\n",
52 fast_tuple_allocs, tuple_zero_allocs);
53 fprintf(stderr, "fast int allocs: pos: %d, neg: %d\n",
54 quick_int_allocs, quick_neg_int_allocs);
55 fprintf(stderr, "null strings: %d, 1-strings: %d\n",
56 null_strings, one_strings);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000057}
58
59void
60inc_count(tp)
61 typeobject *tp;
62{
63 if (tp->tp_alloc == 0) {
64 /* first time; hang in linked list */
65 if (tp->tp_next != NULL) /* sanity check */
66 abort();
67 tp->tp_next = type_list;
68 type_list = tp;
69 }
70 tp->tp_alloc++;
71 if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
72 tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
73}
74#endif
75
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076object *
77newobject(tp)
78 typeobject *tp;
79{
80 object *op = (object *) malloc(tp->tp_basicsize);
81 if (op == NULL)
82 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000083 op->ob_type = tp;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000084 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000085 return op;
86}
87
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088varobject *
89newvarobject(tp, size)
90 typeobject *tp;
91 unsigned int size;
92{
93 varobject *op = (varobject *)
94 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
95 if (op == NULL)
Guido van Rossum05ab1111991-05-05 20:10:41 +000096 return (varobject *)err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000097 op->ob_type = tp;
98 op->ob_size = size;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000099 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000100 return op;
101}
102
Guido van Rossum90933611991-06-07 16:10:43 +0000103int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104printobject(op, fp, flags)
105 object *op;
106 FILE *fp;
107 int flags;
108{
Guido van Rossum278ef591991-07-27 21:40:24 +0000109 int ret = 0;
Guido van Rossum90933611991-06-07 16:10:43 +0000110 if (intrcheck()) {
111 err_set(KeyboardInterrupt);
112 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000113 }
Guido van Rossum90933611991-06-07 16:10:43 +0000114 if (op == NULL) {
115 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000116 }
Guido van Rossum90933611991-06-07 16:10:43 +0000117 else {
118 if (op->ob_refcnt <= 0)
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000119 fprintf(fp, "<refcnt %u at %lx>",
120 op->ob_refcnt, (long)op);
121 else if (op->ob_type->tp_print == NULL) {
122 if (op->ob_type->tp_repr == NULL) {
123 fprintf(fp, "<%s object at %lx>",
124 op->ob_type->tp_name, (long)op);
125 }
126 else {
127 object *s = reprobject(op);
128 if (s == NULL)
129 ret = -1;
130 else if (!is_stringobject(s)) {
131 err_setstr(TypeError,
132 "repr not string");
133 ret = -1;
134 }
135 else {
136 fprintf(fp, "%s", getstringvalue(s));
137 }
138 XDECREF(s);
139 }
140 }
Guido van Rossum90933611991-06-07 16:10:43 +0000141 else
Guido van Rossum278ef591991-07-27 21:40:24 +0000142 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +0000143 }
Guido van Rossum278ef591991-07-27 21:40:24 +0000144 if (ret == 0) {
145 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +0000146 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +0000147 clearerr(fp);
148 ret = -1;
149 }
150 }
151 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152}
153
154object *
155reprobject(v)
156 object *v;
157{
Guido van Rossum90933611991-06-07 16:10:43 +0000158 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000160 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000161 }
Guido van Rossum90933611991-06-07 16:10:43 +0000162 if (v == NULL)
163 return newstringobject("<NULL>");
164 else if (v->ob_type->tp_repr == NULL) {
165 char buf[120];
166 sprintf(buf, "<%.80s object at %lx>",
167 v->ob_type->tp_name, (long)v);
168 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000169 }
Guido van Rossum90933611991-06-07 16:10:43 +0000170 else
171 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000172}
173
174int
175cmpobject(v, w)
176 object *v, *w;
177{
178 typeobject *tp;
179 if (v == w)
180 return 0;
181 if (v == NULL)
182 return -1;
183 if (w == NULL)
184 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000185 if ((tp = v->ob_type) != w->ob_type) {
186 if (tp->tp_as_number != NULL &&
187 w->ob_type->tp_as_number != NULL) {
188 if (coerce(&v, &w) != 0) {
189 err_clear();
190 /* XXX Should report the error,
191 XXX but the interface isn't there... */
192 }
193 else {
194 int cmp = (*v->ob_type->tp_compare)(v, w);
195 DECREF(v);
196 DECREF(w);
197 return cmp;
198 }
199 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000200 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000201 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202 if (tp->tp_compare == NULL)
203 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000204 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205}
206
Guido van Rossum9bfef441993-03-29 10:43:31 +0000207long
208hashobject(v)
209 object *v;
210{
211 typeobject *tp = v->ob_type;
212 if (tp->tp_hash != NULL)
213 return (*tp->tp_hash)(v);
214 if (tp->tp_compare == NULL)
215 return (long) v; /* Use address as hash value */
216 /* If there's a cmp but no hash defined, the object can't be hashed */
217 err_setstr(TypeError, "unhashable type");
218 return -1;
219}
220
Guido van Rossum3f5da241990-12-20 15:06:42 +0000221object *
222getattr(v, name)
223 object *v;
224 char *name;
225{
226 if (v->ob_type->tp_getattr == NULL) {
227 err_setstr(TypeError, "attribute-less object");
228 return NULL;
229 }
230 else {
231 return (*v->ob_type->tp_getattr)(v, name);
232 }
233}
234
235int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000236hasattr(v, name)
237 object *v;
238 char *name;
239{
240 object *res = getattr(v, name);
241 if (res != NULL) {
242 DECREF(res);
243 return 1;
244 }
245 err_clear();
246 return 0;
247}
248
249int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250setattr(v, name, w)
251 object *v;
252 char *name;
253 object *w;
254{
255 if (v->ob_type->tp_setattr == NULL) {
256 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000257 err_setstr(TypeError,
258 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000259 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000260 err_setstr(TypeError,
261 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000262 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000263 }
264 else {
265 return (*v->ob_type->tp_setattr)(v, name, w);
266 }
267}
268
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000269/* Test a value used as condition, e.g., in a for or if statement.
270 Return -1 if an error occurred */
271
272int
273testbool(v)
274 object *v;
275{
276 int res;
277 if (v == None)
278 res = 0;
279 else if (v->ob_type->tp_as_number != NULL)
280 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
281 else if (v->ob_type->tp_as_mapping != NULL)
282 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
283 else if (v->ob_type->tp_as_sequence != NULL)
284 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
285 else
286 res = 1;
287 if (res > 0)
288 res = 1;
289 return res;
290}
291
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000292
293/*
294NoObject is usable as a non-NULL undefined value, used by the macro None.
295There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000296so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000297*/
298
Guido van Rossum0c182a11992-03-27 17:26:13 +0000299/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000300static object *
301none_repr(op)
302 object *op;
303{
304 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000305}
306
307static typeobject Notype = {
308 OB_HEAD_INIT(&Typetype)
309 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000310 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000311 0,
312 0,
313 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000314 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000315 0, /*tp_getattr*/
316 0, /*tp_setattr*/
317 0, /*tp_compare*/
318 none_repr, /*tp_repr*/
319 0, /*tp_as_number*/
320 0, /*tp_as_sequence*/
321 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000322 0, /*tp_hash */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000323};
324
325object NoObject = {
326 OB_HEAD_INIT(&Notype)
327};
328
329
330#ifdef TRACE_REFS
331
332static object refchain = {&refchain, &refchain};
333
334NEWREF(op)
335 object *op;
336{
337 ref_total++;
338 op->ob_refcnt = 1;
339 op->_ob_next = refchain._ob_next;
340 op->_ob_prev = &refchain;
341 refchain._ob_next->_ob_prev = op;
342 refchain._ob_next = op;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000343#ifdef COUNT_ALLOCS
344 inc_count(op->ob_type);
345#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000346}
347
Guido van Rossum3f5da241990-12-20 15:06:42 +0000348UNREF(op)
349 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000350{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000351 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000352 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000353 fprintf(stderr, "UNREF negative refcnt\n");
354 abort();
355 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000356 if (op == &refchain ||
357 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
358 fprintf(stderr, "UNREF invalid object\n");
359 abort();
360 }
361#ifdef SLOW_UNREF_CHECK
Guido van Rossum3f5da241990-12-20 15:06:42 +0000362 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
363 if (p == op)
364 break;
365 }
366 if (p == &refchain) { /* Not found */
367 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000368 abort();
369 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000370#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000371 op->_ob_next->_ob_prev = op->_ob_prev;
372 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000373 op->_ob_next = op->_ob_prev = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000374}
375
376DELREF(op)
377 object *op;
378{
379 UNREF(op);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000380#ifdef COUNT_ALLOCS
381 op->ob_type->tp_free++;
382#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383 (*(op)->ob_type->tp_dealloc)(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000384 op->ob_type = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000385}
386
387printrefs(fp)
388 FILE *fp;
389{
390 object *op;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000391 fprintf(fp, "Remaining objects (except strings referenced once):\n");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000392 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000393 if (op->ob_refcnt == 1 && is_stringobject(op))
394 continue; /* Will be printed elsewhere */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000395 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000396 if (printobject(op, fp, 0) != 0)
397 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000398 putc('\n', fp);
399 }
400}
401
402#endif