blob: 7a7383e08aa279d7bd58faf5b9e08f2bc9f88ef3 [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 {
Guido van Rossumc6004111993-11-05 10:22:19 +0000127 object *s;
128 if (flags & PRINT_RAW)
129 s = strobject(op);
130 else
131 s = reprobject(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000132 if (s == NULL)
133 ret = -1;
134 else if (!is_stringobject(s)) {
135 err_setstr(TypeError,
136 "repr not string");
137 ret = -1;
138 }
139 else {
140 fprintf(fp, "%s", getstringvalue(s));
141 }
142 XDECREF(s);
143 }
144 }
Guido van Rossum90933611991-06-07 16:10:43 +0000145 else
Guido van Rossum278ef591991-07-27 21:40:24 +0000146 ret = (*op->ob_type->tp_print)(op, fp, flags);
Guido van Rossum90933611991-06-07 16:10:43 +0000147 }
Guido van Rossum278ef591991-07-27 21:40:24 +0000148 if (ret == 0) {
149 if (ferror(fp)) {
Guido van Rossum2912f221991-12-10 13:59:09 +0000150 err_errno(IOError);
Guido van Rossum278ef591991-07-27 21:40:24 +0000151 clearerr(fp);
152 ret = -1;
153 }
154 }
155 return ret;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000156}
157
158object *
159reprobject(v)
160 object *v;
161{
Guido van Rossum90933611991-06-07 16:10:43 +0000162 if (intrcheck()) {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000163 err_set(KeyboardInterrupt);
Guido van Rossum90933611991-06-07 16:10:43 +0000164 return NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000165 }
Guido van Rossum90933611991-06-07 16:10:43 +0000166 if (v == NULL)
167 return newstringobject("<NULL>");
168 else if (v->ob_type->tp_repr == NULL) {
169 char buf[120];
170 sprintf(buf, "<%.80s object at %lx>",
171 v->ob_type->tp_name, (long)v);
172 return newstringobject(buf);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000173 }
Guido van Rossum90933611991-06-07 16:10:43 +0000174 else
175 return (*v->ob_type->tp_repr)(v);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000176}
177
Guido van Rossumc6004111993-11-05 10:22:19 +0000178object *
179strobject(v)
180 object *v;
181{
182 if (v == NULL)
183 return newstringobject("<NULL>");
184 if (is_stringobject(v)) {
185 INCREF(v);
186 return v;
187 }
188 else {
189 object *func = getattr(v, "__str__");
190 object *args;
191 object *res;
192 if (func == NULL) {
193 err_clear();
194 return reprobject(v);
195 }
196 args = newtupleobject(0);
197 if (args == NULL)
198 res = NULL;
199 else {
200 res = call_object(func, args);
201 DECREF(args);
202 }
203 DECREF(func);
204 return res;
205 }
206}
207
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000208int
209cmpobject(v, w)
210 object *v, *w;
211{
212 typeobject *tp;
213 if (v == w)
214 return 0;
215 if (v == NULL)
216 return -1;
217 if (w == NULL)
218 return 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000219 if ((tp = v->ob_type) != w->ob_type) {
220 if (tp->tp_as_number != NULL &&
221 w->ob_type->tp_as_number != NULL) {
222 if (coerce(&v, &w) != 0) {
223 err_clear();
224 /* XXX Should report the error,
225 XXX but the interface isn't there... */
226 }
227 else {
228 int cmp = (*v->ob_type->tp_compare)(v, w);
229 DECREF(v);
230 DECREF(w);
231 return cmp;
232 }
233 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000234 return strcmp(tp->tp_name, w->ob_type->tp_name);
Guido van Rossum9fb03681991-07-01 18:48:04 +0000235 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000236 if (tp->tp_compare == NULL)
237 return (v < w) ? -1 : 1;
Guido van Rossum9fb03681991-07-01 18:48:04 +0000238 return (*tp->tp_compare)(v, w);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000239}
240
Guido van Rossum9bfef441993-03-29 10:43:31 +0000241long
242hashobject(v)
243 object *v;
244{
245 typeobject *tp = v->ob_type;
246 if (tp->tp_hash != NULL)
247 return (*tp->tp_hash)(v);
248 if (tp->tp_compare == NULL)
249 return (long) v; /* Use address as hash value */
250 /* If there's a cmp but no hash defined, the object can't be hashed */
251 err_setstr(TypeError, "unhashable type");
252 return -1;
253}
254
Guido van Rossum3f5da241990-12-20 15:06:42 +0000255object *
256getattr(v, name)
257 object *v;
258 char *name;
259{
260 if (v->ob_type->tp_getattr == NULL) {
261 err_setstr(TypeError, "attribute-less object");
262 return NULL;
263 }
264 else {
265 return (*v->ob_type->tp_getattr)(v, name);
266 }
267}
268
269int
Guido van Rossumed18fdc1993-07-11 19:55:34 +0000270hasattr(v, name)
271 object *v;
272 char *name;
273{
274 object *res = getattr(v, name);
275 if (res != NULL) {
276 DECREF(res);
277 return 1;
278 }
279 err_clear();
280 return 0;
281}
282
283int
Guido van Rossum3f5da241990-12-20 15:06:42 +0000284setattr(v, name, w)
285 object *v;
286 char *name;
287 object *w;
288{
289 if (v->ob_type->tp_setattr == NULL) {
290 if (v->ob_type->tp_getattr == NULL)
Guido van Rossum3ea74121991-12-24 13:28:03 +0000291 err_setstr(TypeError,
292 "attribute-less object (assign or del)");
Guido van Rossum3f5da241990-12-20 15:06:42 +0000293 else
Guido van Rossum3ea74121991-12-24 13:28:03 +0000294 err_setstr(TypeError,
295 "object has read-only attributes");
Guido van Rossum73531a31990-12-20 23:12:40 +0000296 return -1;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000297 }
298 else {
299 return (*v->ob_type->tp_setattr)(v, name, w);
300 }
301}
302
Guido van Rossum6ac258d1993-05-12 08:24:20 +0000303/* Test a value used as condition, e.g., in a for or if statement.
304 Return -1 if an error occurred */
305
306int
307testbool(v)
308 object *v;
309{
310 int res;
311 if (v == None)
312 res = 0;
313 else if (v->ob_type->tp_as_number != NULL)
314 res = (*v->ob_type->tp_as_number->nb_nonzero)(v);
315 else if (v->ob_type->tp_as_mapping != NULL)
316 res = (*v->ob_type->tp_as_mapping->mp_length)(v);
317 else if (v->ob_type->tp_as_sequence != NULL)
318 res = (*v->ob_type->tp_as_sequence->sq_length)(v);
319 else
320 res = 1;
321 if (res > 0)
322 res = 1;
323 return res;
324}
325
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000326
327/*
328NoObject is usable as a non-NULL undefined value, used by the macro None.
329There is (and should be!) no way to create other objects of this type,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000330so there is exactly one (which is indestructible, by the way).
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000331*/
332
Guido van Rossum0c182a11992-03-27 17:26:13 +0000333/* ARGSUSED */
Guido van Rossum3f5da241990-12-20 15:06:42 +0000334static object *
335none_repr(op)
336 object *op;
337{
338 return newstringobject("None");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000339}
340
341static typeobject Notype = {
342 OB_HEAD_INIT(&Typetype)
343 0,
Guido van Rossum3f5da241990-12-20 15:06:42 +0000344 "None",
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000345 0,
346 0,
347 0, /*tp_dealloc*/ /*never called*/
Guido van Rossum7066dd71992-09-17 17:54:56 +0000348 0, /*tp_print*/
Guido van Rossum3f5da241990-12-20 15:06:42 +0000349 0, /*tp_getattr*/
350 0, /*tp_setattr*/
351 0, /*tp_compare*/
352 none_repr, /*tp_repr*/
353 0, /*tp_as_number*/
354 0, /*tp_as_sequence*/
355 0, /*tp_as_mapping*/
Guido van Rossum9bfef441993-03-29 10:43:31 +0000356 0, /*tp_hash */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000357};
358
359object NoObject = {
360 OB_HEAD_INIT(&Notype)
361};
362
363
364#ifdef TRACE_REFS
365
366static object refchain = {&refchain, &refchain};
367
368NEWREF(op)
369 object *op;
370{
371 ref_total++;
372 op->ob_refcnt = 1;
373 op->_ob_next = refchain._ob_next;
374 op->_ob_prev = &refchain;
375 refchain._ob_next->_ob_prev = op;
376 refchain._ob_next = op;
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000377#ifdef COUNT_ALLOCS
378 inc_count(op->ob_type);
379#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000380}
381
Guido van Rossum3f5da241990-12-20 15:06:42 +0000382UNREF(op)
383 register object *op;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000384{
Guido van Rossum3f5da241990-12-20 15:06:42 +0000385 register object *p;
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000386 if (op->ob_refcnt < 0) {
Guido van Rossum3f5da241990-12-20 15:06:42 +0000387 fprintf(stderr, "UNREF negative refcnt\n");
388 abort();
389 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000390 if (op == &refchain ||
391 op->_ob_prev->_ob_next != op || op->_ob_next->_ob_prev != op) {
392 fprintf(stderr, "UNREF invalid object\n");
393 abort();
394 }
395#ifdef SLOW_UNREF_CHECK
Guido van Rossum3f5da241990-12-20 15:06:42 +0000396 for (p = refchain._ob_next; p != &refchain; p = p->_ob_next) {
397 if (p == op)
398 break;
399 }
400 if (p == &refchain) { /* Not found */
401 fprintf(stderr, "UNREF unknown object\n");
Guido van Rossumbd3edc81990-11-02 17:49:51 +0000402 abort();
403 }
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000404#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000405 op->_ob_next->_ob_prev = op->_ob_prev;
406 op->_ob_prev->_ob_next = op->_ob_next;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000407 op->_ob_next = op->_ob_prev = NULL;
Guido van Rossum3f5da241990-12-20 15:06:42 +0000408}
409
410DELREF(op)
411 object *op;
412{
413 UNREF(op);
Sjoerd Mullendera9c3c221993-10-11 12:54:31 +0000414#ifdef COUNT_ALLOCS
415 op->ob_type->tp_free++;
416#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000417 (*(op)->ob_type->tp_dealloc)(op);
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000418 op->ob_type = NULL;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000419}
420
421printrefs(fp)
422 FILE *fp;
423{
424 object *op;
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000425 fprintf(fp, "Remaining objects (except strings referenced once):\n");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000426 for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
Guido van Rossum2e8f6141992-09-03 20:32:55 +0000427 if (op->ob_refcnt == 1 && is_stringobject(op))
428 continue; /* Will be printed elsewhere */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000429 fprintf(fp, "[%d] ", op->ob_refcnt);
Guido van Rossum90933611991-06-07 16:10:43 +0000430 if (printobject(op, fp, 0) != 0)
431 err_clear();
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000432 putc('\n', fp);
433 }
434}
435
436#endif