blob: a20b24d958f1bb4fcb617da095bb8c889aa2897b [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;
39
40void
41dump_counts()
42{
43 typeobject *tp;
44
45 for (tp = type_list; tp; tp = tp->tp_next)
46 printf("%s %d %d %d\n", tp->tp_name, tp->tp_alloc, tp->tp_free,
47 tp->tp_maxalloc);
48}
49
50void
51inc_count(tp)
52 typeobject *tp;
53{
54 if (tp->tp_alloc == 0) {
55 /* first time; hang in linked list */
56 if (tp->tp_next != NULL) /* sanity check */
57 abort();
58 tp->tp_next = type_list;
59 type_list = tp;
60 }
61 tp->tp_alloc++;
62 if (tp->tp_alloc - tp->tp_free > tp->tp_maxalloc)
63 tp->tp_maxalloc = tp->tp_alloc - tp->tp_free;
64}
65#endif
66
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000067object *
68newobject(tp)
69 typeobject *tp;
70{
71 object *op = (object *) malloc(tp->tp_basicsize);
72 if (op == NULL)
73 return err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000074 op->ob_type = tp;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000075 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000076 return op;
77}
78
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000079varobject *
80newvarobject(tp, size)
81 typeobject *tp;
82 unsigned int size;
83{
84 varobject *op = (varobject *)
85 malloc(tp->tp_basicsize + size * tp->tp_itemsize);
86 if (op == NULL)
Guido van Rossum05ab1111991-05-05 20:10:41 +000087 return (varobject *)err_nomem();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000088 op->ob_type = tp;
89 op->ob_size = size;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +000090 NEWREF(op);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091 return op;
92}
93
Guido van Rossum90933611991-06-07 16:10:43 +000094int
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000095printobject(op, fp, flags)
96 object *op;
97 FILE *fp;
98 int flags;
99{
Guido van Rossum278ef591991-07-27 21:40:24 +0000100 int ret = 0;
Guido van Rossum90933611991-06-07 16:10:43 +0000101 if (intrcheck()) {
102 err_set(KeyboardInterrupt);
103 return -1;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000104 }
Guido van Rossum90933611991-06-07 16:10:43 +0000105 if (op == NULL) {
106 fprintf(fp, "<nil>");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000107 }
Guido van Rossum90933611991-06-07 16:10:43 +0000108 else {
109 if (op->ob_refcnt <= 0)
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000110 fprintf(fp, "<refcnt %u at %lx>",
111 op->ob_refcnt, (long)op);
112 else if (op->ob_type->tp_print == NULL) {
113 if (op->ob_type->tp_repr == NULL) {
114 fprintf(fp, "<%s object at %lx>",
115 op->ob_type->tp_name, (long)op);
116 }
117 else {
118 object *s = reprobject(op);
119 if (s == NULL)
120 ret = -1;
121 else if (!is_stringobject(s)) {
122 err_setstr(TypeError,
123 "repr not string");
124 ret = -1;
125 }
126 else {
127 fprintf(fp, "%s", getstringvalue(s));
128 }
129 XDECREF(s);
130 }
131 }
Guido van Rossum90933611991-06-07 16:10:43 +0000132 else
Guido van Rossum278ef591991-07-27 21:40:24 +0000133 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +0000134 }
Guido van Rossum278ef591991-07-27 21:40:24 +0000135 if (ret == 0) {
136 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +0000137 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +0000138 clearerr(fp);
139 ret = -1;
140 }
141 }
142 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000143}
144
145object *
146reprobject(v)
147 object *v;
148{
Guido van Rossum90933611991-06-07 16:10:43 +0000149 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000150 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000151 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000152 }
Guido van Rossum90933611991-06-07 16:10:43 +0000153 if (v == NULL)
154 return newstringobject("<NULL>");
155 else if (v->ob_type->tp_repr == NULL) {
156 char buf[120];
157 sprintf(buf, "<%.80s object at %lx>",
158 v->ob_type->tp_name, (long)v);
159 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000160 }
Guido van Rossum90933611991-06-07 16:10:43 +0000161 else
162 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163}
164
165int
166cmpobject(v, w)
167 object *v, *w;
168{
169 typeobject *tp;
170 if (v == w)
171 return 0;
172 if (v == NULL)
173 return -1;
174 if (w == NULL)
175 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000176 if ((tp = v->ob_type) != w->ob_type) {
177 if (tp->tp_as_number != NULL &&
178 w->ob_type->tp_as_number != NULL) {
179 if (coerce(&v, &w) != 0) {
180 err_clear();
181 /* XXX Should report the error,
182 XXX but the interface isn't there... */
183 }
184 else {
185 int cmp = (*v->ob_type->tp_compare)(v, w);
186 DECREF(v);
187 DECREF(w);
188 return cmp;
189 }
190 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000191 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000192 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000193 if (tp->tp_compare == NULL)
194 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000195 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000196}
197
Guido van Rossum9bfef441993-03-29 10:43:31 +0000198long
199hashobject(v)
200 object *v;
201{
202 typeobject *tp = v->ob_type;
203 if (tp->tp_hash != NULL)
204 return (*tp->tp_hash)(v);
205 if (tp->tp_compare == NULL)
206 return (long) v; /* Use address as hash value */
207 /* If there's a cmp but no hash defined, the object can't be hashed */
208 err_setstr(TypeError, "unhashable type");
209 return -1;
210}
211
Guido van Rossum3f5da241990-12-20 15:06:42 +0000212object *
213getattr(v, name)
214 object *v;
215 char *name;
216{
217 if (v->ob_type->tp_getattr == NULL) {
218 err_setstr(TypeError, "attribute-less object");
219 return NULL;
220 }
221 else {
222 return (*v->ob_type->tp_getattr)(v, name);
223 }
224}
225
226int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000227hasattr(v, name)
228 object *v;
229 char *name;
230{
231 object *res = getattr(v, name);
232 if (res != NULL) {
233 DECREF(res);
234 return 1;
235 }
236 err_clear();
237 return 0;
238}
239
240int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000241setattr(v, name, w)
242 object *v;
243 char *name;
244 object *w;
245{
246 if (v->ob_type->tp_setattr == NULL) {
247 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000248 err_setstr(TypeError,
249 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000250 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000251 err_setstr(TypeError,
252 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000253 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000254 }
255 else {
256 return (*v->ob_type->tp_setattr)(v, name, w);
257 }
258}
259
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000260/* Test a value used as condition, e.g., in a for or if statement.
261 Return -1 if an error occurred */
262
263int
264testbool(v)
265 object *v;
266{
267 int res;
268 if (v == None)
269 res = 0;
270 else if (v->ob_type->tp_as_number != NULL)
271 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
272 else if (v->ob_type->tp_as_mapping != NULL)
273 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
274 else if (v->ob_type->tp_as_sequence != NULL)
275 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
276 else
277 res = 1;
278 if (res > 0)
279 res = 1;
280 return res;
281}
282
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000283
284/*
285NoObject is usable as a non-NULL undefined value, used by the macro None.
286There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000287so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000288*/
289
Guido van Rossum0c182a11992-03-27 17:26:13 +0000290/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000291static object *
292none_repr(op)
293 object *op;
294{
295 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000296}
297
298static typeobject Notype = {
299 OB_HEAD_INIT(&Typetype)
300 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000301 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000302 0,
303 0,
304 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000305 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000306 0, /*tp_getattr*/
307 0, /*tp_setattr*/
308 0, /*tp_compare*/
309 none_repr, /*tp_repr*/
310 0, /*tp_as_number*/
311 0, /*tp_as_sequence*/
312 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000313 0, /*tp_hash */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000314};
315
316object NoObject = {
317 OB_HEAD_INIT(&Notype)
318};
319
320
321#ifdef TRACE_REFS
322
323static object refchain = {&refchain, &refchain};
324
325NEWREF(op)
326 object *op;
327{
328 ref_total++;
329 op->ob_refcnt = 1;
330 op->_ob_next = refchain._ob_next;
331 op->_ob_prev = &refchain;
332 refchain._ob_next->_ob_prev = op;
333 refchain._ob_next = op;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000334#ifdef COUNT_ALLOCS
335 inc_count(op->ob_type);
336#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000337}
338
Guido van Rossum3f5da241990-12-20 15:06:42 +0000339UNREF(op)
340 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000341{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000342 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000343 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000344 fprintf(stderr, "UNREF negative refcnt\n");
345 abort();
346 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000347 if (op == &refchain ||
348 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
349 fprintf(stderr, "UNREF invalid object\n");
350 abort();
351 }
352#ifdef SLOW_UNREF_CHECK
Guido van Rossum3f5da241990-12-20 15:06:42 +0000353 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
354 if (p == op)
355 break;
356 }
357 if (p == &refchain) { /* Not found */
358 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000359 abort();
360 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000361#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000362 op->_ob_next->_ob_prev = op->_ob_prev;
363 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000364 op->_ob_next = op->_ob_prev = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000365}
366
367DELREF(op)
368 object *op;
369{
370 UNREF(op);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000371#ifdef COUNT_ALLOCS
372 op->ob_type->tp_free++;
373#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000374 (*(op)->ob_type->tp_dealloc)(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000375 op->ob_type = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000376}
377
378printrefs(fp)
379 FILE *fp;
380{
381 object *op;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000382 fprintf(fp, "Remaining objects (except strings referenced once):\n");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000383 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000384 if (op->ob_refcnt == 1 && is_stringobject(op))
385 continue; /* Will be printed elsewhere */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000386 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000387 if (printobject(op, fp, 0) != 0)
388 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000389 putc('\n', fp);
390 }
391}
392
393#endif