1 /***********************************************************
2 Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
3 Amsterdam, The Netherlands.
7 Permission to use, copy, modify, and distribute this software and its
8 documentation for any purpose and without fee is hereby granted,
9 provided that the above copyright notice appear in all copies and that
10 both that copyright notice and this permission notice appear in
11 supporting documentation, and that the names of Stichting Mathematisch
12 Centrum or CWI not be used in advertising or publicity pertaining to
13 distribution of the software without specific, written prior permission.
15 STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18 FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21 OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 ******************************************************************/
25 /* Generic object operations; and implementation of None (NoObject) */
27 #include "allobjects.h"
33 /* 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! */
38 static typeobject
*type_list
;
39 extern int tuple_zero_allocs
, fast_tuple_allocs
;
40 extern int quick_int_allocs
, quick_neg_int_allocs
;
41 extern int null_strings
, one_strings
;
47 for (tp
= type_list
; tp
; tp
= tp
->tp_next
)
48 fprintf(stderr
, "%s alloc'd: %d, freed: %d, max in use: %d\n",
49 tp
->tp_name
, tp
->tp_alloc
, tp
->tp_free
,
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
);
63 if (tp
->tp_alloc
== 0) {
64 /* first time; hang in linked list */
65 if (tp
->tp_next
!= NULL
) /* sanity check */
67 tp
->tp_next
= type_list
;
71 if (tp
->tp_alloc
- tp
->tp_free
> tp
->tp_maxalloc
)
72 tp
->tp_maxalloc
= tp
->tp_alloc
- tp
->tp_free
;
80 object
*op
= (object
*) malloc(tp
->tp_basicsize
);
89 newvarobject(tp
, size
)
93 varobject
*op
= (varobject
*)
94 malloc(tp
->tp_basicsize
+ size
* tp
->tp_itemsize
);
96 return (varobject
*)err_nomem();
104 printobject(op
, fp
, flags
)
111 err_set(KeyboardInterrupt
);
115 fprintf(fp
, "<nil>");
118 if (op
->ob_refcnt
<= 0)
119 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
);
128 if (flags
& PRINT_RAW
)
134 else if (!is_stringobject(s
)) {
135 err_setstr(TypeError
,
140 fprintf(fp
, "%s", getstringvalue(s
));
146 ret
= (*op
->ob_type
->tp_print
)(op
, fp
, flags
);
163 err_set(KeyboardInterrupt
);
167 return newstringobject("<NULL>");
168 else if (v
->ob_type
->tp_repr
== NULL
) {
170 sprintf(buf
, "<%.80s object at %lx>",
171 v
->ob_type
->tp_name
, (long)v
);
172 return newstringobject(buf
);
175 return (*v
->ob_type
->tp_repr
)(v
);
183 return newstringobject("<NULL>");
184 if (is_stringobject(v
)) {
189 object
*func
= getattr(v
, "__str__");
194 return reprobject(v
);
196 args
= newtupleobject(0);
200 res
= call_object(func
, args
);
219 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) {
224 /* XXX Should report the error,
225 XXX but the interface isn't there... */
228 int cmp
= (*v
->ob_type
->tp_compare
)(v
, w
);
234 return strcmp(tp
->tp_name
, w
->ob_type
->tp_name
);
236 if (tp
->tp_compare
== NULL
)
237 return (v
< w
) ? -1 : 1;
238 return (*tp
->tp_compare
)(v
, w
);
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");
260 if (v
->ob_type
->tp_getattr
== NULL
) {
261 err_setstr(TypeError
, "attribute-less object");
265 return (*v
->ob_type
->tp_getattr
)(v
, name
);
274 object
*res
= getattr(v
, name
);
289 if (v
->ob_type
->tp_setattr
== NULL
) {
290 if (v
->ob_type
->tp_getattr
== NULL
)
291 err_setstr(TypeError
,
292 "attribute-less object (assign or del)");
294 err_setstr(TypeError
,
295 "object has read-only attributes");
299 return (*v
->ob_type
->tp_setattr
)(v
, name
, w
);
303 /* Test a value used as condition, e.g., in a for or if statement.
304 Return -1 if an error occurred */
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
);
328 NoObject is usable as a non-NULL undefined value, used by the macro None.
329 There is (and should be!) no way to create other objects of this type,
330 so there is exactly one (which is indestructible, by the way).
338 return newstringobject("None");
341 static typeobject Notype
= {
342 OB_HEAD_INIT(&Typetype
)
347 0, /*tp_dealloc*/ /*never called*/
352 (reprfunc
)none_repr
, /*tp_repr*/
354 0, /*tp_as_sequence*/
360 OB_HEAD_INIT(&Notype
)
366 static object refchain
= {&refchain
, &refchain
};
373 op
->_ob_next
= refchain
._ob_next
;
374 op
->_ob_prev
= &refchain
;
375 refchain
._ob_next
->_ob_prev
= op
;
376 refchain
._ob_next
= op
;
378 inc_count(op
->ob_type
);
386 if (op
->ob_refcnt
< 0) {
387 fprintf(stderr
, "UNREF negative refcnt\n");
390 if (op
== &refchain
||
391 op
->_ob_prev
->_ob_next
!= op
|| op
->_ob_next
->_ob_prev
!= op
) {
392 fprintf(stderr
, "UNREF invalid object\n");
395 #ifdef SLOW_UNREF_CHECK
396 for (p
= refchain
._ob_next
; p
!= &refchain
; p
= p
->_ob_next
) {
400 if (p
== &refchain
) { /* Not found */
401 fprintf(stderr
, "UNREF unknown object\n");
405 op
->_ob_next
->_ob_prev
= op
->_ob_prev
;
406 op
->_ob_prev
->_ob_next
= op
->_ob_next
;
407 op
->_ob_next
= op
->_ob_prev
= NULL
;
415 op
->ob_type
->tp_free
++;
417 (*(op
)->ob_type
->tp_dealloc
)(op
);
425 fprintf(fp
, "Remaining objects (except strings referenced once):\n");
426 for (op
= refchain
._ob_next
; op
!= &refchain
; op
= op
->_ob_next
) {
427 if (op
->ob_refcnt
== 1 && is_stringobject(op
))
428 continue; /* Will be printed elsewhere */
429 fprintf(fp
, "[%d] ", op
->ob_refcnt
);
430 if (printobject(op
, fp
, 0) != 0)