]> www.ginac.de Git - cln.git/blob - include/cln/object.h
Assume types 'long long int' and 'long double' exist.
[cln.git] / include / cln / object.h
1 // General object definitions: pointers, reference counting, garbage collection.
2
3 #ifndef _CL_OBJECT_H
4 #define _CL_OBJECT_H
5
6 #include "cln/types.h"
7 #include "cln/modules.h"
8 #include <cstdlib>
9
10 namespace cln {
11
12 // We don't have to deal with circular structures, so normal reference counting
13 // is sufficient. Is also has the advantage of being mostly non-interrupting.
14
15
16 // An object is either a pointer to heap allocated data
17 //              or immediate data.
18
19 // It is possible to distinguish these because pointers are aligned.
20 // cl_word_alignment is the guaranteed alignment of a `void*' or `long'
21 // in memory. Must be > 1.
22 #if defined(__m68k__)
23   #define cl_word_alignment  2
24 #endif
25 #if defined(__i386__) || (defined(__mips__) && !defined(__LP64__)) || (defined(__sparc__) && !defined(__arch64__)) || defined(__hppa__) || defined(__arm__) || defined(__rs6000__) || defined(__m88k__) || defined(__convex__) || (defined(__s390__) && !defined(__s390x__)) || defined(__sh__) || (defined(__x86_64__) && defined(__ILP32__))
26   #define cl_word_alignment  4
27 #endif
28 #if defined(__alpha__) || defined(__ia64__) || defined(__mips64__) || defined(__powerpc64__) || (defined(__sparc__) && defined(__arch64__)) || (defined(__x86_64__) && !defined(__ILP32__)) || defined(__s390x__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64) || defined(__e2k__)
29   #define cl_word_alignment  8
30 #endif
31 #if !defined(cl_word_alignment)
32   #error "Define cl_word_alignment for your CPU!"
33 #endif
34
35
36 // Four basic classes are introduced:
37 //
38 //   gcobject      rcobject
39 //
40 //   gcpointer     rcpointer
41 //
42 // `gcobject' = garbage collectible object (pointer or immediate),
43 // `gcpointer' = garbage collectible pointer,
44 // `rcobject' = reference counted object (pointer or immediate),
45 // `rcpointer' = reference counted pointer.
46 //
47 // "garbage collectible" means that a reference count is maintained, and
48 // when the reference count drops to 0, the object is freed. This is useful
49 // for all kind of short- or long-lived objects.
50 // "reference counted" means that a reference count is maintained, which
51 // cannot drop to 0. This is useful for objects which are registered in a
52 // global cache table, in order to know which objects can be thrown away
53 // when the cache is cleaned. (If the cache were never cleaned, its objects
54 // would never be freed, and we could get away with normal C pointers.)
55 //
56 // It is permissible to treat a `rcobject' as a `gcobject', and a `rcpointer'
57 // as a `gcpointer', but this just increases the destructor and copy-constructor
58 // overhead.
59 // It is also permissible to treat a `gcpointer' as a `gcobject', and a
60 // `rcpointer' as a `rcobject', but this just increases the destructor and
61 // copy-constructor overhead.
62
63
64 // Immediate data is a word, as wide as a pointer.
65 typedef sintP  cl_sint;
66 typedef uintP  cl_uint;  // This ought to be called `cl_word'.
67 #define cl_pointer_size intPsize
68 // NB: (cl_pointer_size==64) implies defined(HAVE_FAST_LONGLONG)
69 #if (cl_pointer_size==64)
70   #define CL_WIDE_POINTERS
71 #endif
72
73 // Distinguish immediate data from pointers.
74 inline bool cl_pointer_p (cl_uint word)
75 {
76         return (word & (cl_word_alignment-1)) == 0;
77 }
78 inline bool cl_immediate_p (cl_uint word)
79 {
80         return (word & (cl_word_alignment-1)) != 0;
81 }
82
83 // Immediate data: Fixnum, Short Float, maybe Single Float.
84 // They have type tags.
85 //   |...............................|......|
86 //               cl_value             cl_tag
87
88 // Number of bits reserved for tagging information:
89 #if (cl_word_alignment <= 4)
90   #define cl_tag_len    2
91 #else
92   #define cl_tag_len    3
93 #endif
94 #define cl_tag_shift    0
95 #define cl_value_shift  (cl_tag_len+cl_tag_shift)
96 #define cl_value_len    (cl_pointer_size - cl_value_shift)
97 #define cl_tag_mask     ((((cl_uint)1 << cl_tag_len) - 1) << cl_tag_shift)
98 #define cl_value_mask   ((((cl_uint)1 << cl_value_len) - 1) << cl_value_shift)
99
100 // Return the tag of a word.
101 inline cl_uint cl_tag (cl_uint word)
102 {
103         return (word & cl_tag_mask) >> cl_tag_shift;
104 }
105
106 // Return the value (unsigned) of a word.
107 inline cl_uint cl_value (cl_uint word)
108 {
109         // This assumes cl_value_shift + cl_value_len == cl_pointer_size.
110         return word >> cl_value_shift;
111 }
112
113 // Return a word, combining a value and a tag.
114 inline cl_uint cl_combine_impl (cl_uint tag, cl_uint value)
115 {
116         return (value << cl_value_shift) + (tag << cl_tag_shift);
117 }
118 inline cl_uint cl_combine_impl (cl_uint tag, cl_sint value)
119 {
120         // This assumes cl_value_shift + cl_value_len == cl_pointer_size.
121         return (value << cl_value_shift) + (tag << cl_tag_shift);
122 }
123 inline cl_uint cl_combine (cl_uint tag, unsigned int value)
124 { return cl_combine_impl(tag, (cl_uint)value); }
125 inline cl_uint cl_combine (cl_uint tag, int value)
126 { return cl_combine_impl(tag, (cl_sint)value); }
127 inline cl_uint cl_combine (cl_uint tag, unsigned long value)
128 { return cl_combine_impl(tag, (cl_uint)value); }
129 inline cl_uint cl_combine (cl_uint tag, long value)
130 { return cl_combine_impl(tag, (cl_sint)value); }
131 inline cl_uint cl_combine (cl_uint tag, unsigned long long value)
132 { return cl_combine_impl(tag, (cl_uint)value); }
133 inline cl_uint cl_combine (cl_uint tag, long long value)
134 { return cl_combine_impl(tag, (cl_uint)value); }
135
136 // Definition of the tags.
137 #if !defined(CL_WIDE_POINTERS)
138   #if (cl_word_alignment == 2)
139     #define cl_FN_tag   1
140     #define cl_SF_tag   3       // must satisfy the cl_immediate_p predicate!
141   #endif
142   #if (cl_word_alignment == 4)
143     #define cl_FN_tag   1
144     #define cl_SF_tag   2
145   #endif
146 #else // CL_WIDE_POINTERS
147   // Single Floats are immediate as well.
148   #define cl_FN_tag     1
149   #define cl_SF_tag     2
150   #define cl_FF_tag     3
151 #endif
152
153 // Corresponding classes.
154 extern const struct cl_class * cl_immediate_classes [1<<cl_tag_len];
155
156
157 // Heap allocated data contains a header, for two purposes:
158 // - dynamic typing,
159 // - reference count (a portable alternative to garbage collection,
160 //   or the basis for a portable and interoperable garbage collection).
161 struct cl_heap {
162         int refcount;                   // reference count
163         const struct cl_class * type;   // type tag
164 };
165
166 // Function to destroy the contents of a heap object.
167 typedef void (*cl_heap_destructor_function) (cl_heap* pointer);
168 // Flags, may be ORed together.
169 #define cl_class_flags_subclass_complex   1  // all instances belong to cl_N
170 #define cl_class_flags_subclass_real      2  // all instances belong to cl_R
171 #define cl_class_flags_subclass_float     4  // all instances belong to cl_F
172 #define cl_class_flags_subclass_rational  8  // all instances belong to cl_RA
173 #define cl_class_flags_number_ring       16  // all instances are rings whose
174                                              // elements belong to cl_number
175 #define cl_class_flags_modint_ring       32  // all instances are rings whose
176                                              // elements belong to cl_MI
177 #define cl_class_flags_univpoly_ring     64  // all instances are rings whose
178                                              // elements belong to cl_UP
179 // Function to print an object for debugging, to cerr.
180 typedef void (*cl_heap_dprint_function) (cl_heap* pointer);
181
182 struct cl_class {
183         cl_heap_destructor_function destruct;
184         int flags;
185         cl_heap_dprint_function dprint;
186 };
187
188 // Free an object on heap.
189 extern void cl_free_heap_object (cl_heap* pointer);
190
191 // Debugging support for dynamic typing: Register a debugging print function.
192 #define cl_register_type_printer(type,printer)  \
193   { extern cl_class type; type.dprint = (printer); }
194
195
196 // cl_private_thing: An immediate value or a pointer into the heap.
197 // This must be as wide as a `cl_uint'.
198 // (Actually, this ought to be a  union { void*; cl_uint; }, but using
199 // a pointer type generates better code.)
200 // Never throw away a cl_private_thing, or reference counts will be wrong!
201 typedef struct cl_anything * cl_private_thing;
202
203 // Increment the reference count.
204 inline void cl_inc_pointer_refcount (cl_heap* pointer)
205 {
206         pointer->refcount++;
207 }
208
209 // Decrement the reference count of a garbage collected pointer.
210 inline void cl_gc_dec_pointer_refcount (cl_heap* pointer)
211 {
212         if (--pointer->refcount == 0)
213                 cl_free_heap_object(pointer);
214 }
215 // Decrement the reference count of a reference counted pointer.
216 inline void cl_rc_dec_pointer_refcount (cl_heap* pointer)
217 {
218         --pointer->refcount;
219 }
220
221 // Increment the reference count.
222 // This must be a macro, not an inline function, because pointer_p() and
223 // inc_pointer_refcount() are non-virtual member functions, so that the
224 // compiler can optimize it.
225 #define cl_inc_refcount(x)  \
226         if ((x).pointer_p())                                    \
227                 (x).inc_pointer_refcount();                     \
228
229 // Decrement the reference count.
230 // This must be a macro, not an inline function, because pointer_p() and
231 // dec_pointer_refcount() are non-virtual member functions, so that the
232 // compiler can optimize it.
233 #define cl_dec_refcount(x)  \
234         if ((x).pointer_p())                                    \
235                 (x).dec_pointer_refcount();                     \
236
237 // The declaration of a copy constructor.
238 // Restriction: The base class's default constructor must do nothing or
239 // initialize `pointer' to a constant expression.
240 #define CL_DEFINE_COPY_CONSTRUCTOR1(_class_)                    \
241         _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_class_)
242 #define _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_classname_)       \
243 inline _class_::_classname_ (const _class_& x)                  \
244 {                                                               \
245         cl_uint x_word = x.word;                                \
246         cl_inc_refcount(x);                                     \
247         this->word = x_word;                                    \
248 }
249
250 // The declaration of a copy constructor.
251 // Restriction: The base class must have the usual `cl_private_thing'
252 // constructor. Drawback: The base class must be known here.
253 #define CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_baseclass_)                \
254         _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_class_,_baseclass_)
255 #define _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_classname_,_baseclass_) \
256 inline _class_::_classname_ (const _class_& x)                  \
257         : _baseclass_ (as_cl_private_thing(x)) {}
258
259 // The declaration of an assignment operator.
260 #define CL_DEFINE_ASSIGNMENT_OPERATOR(dest_class,src_class)     \
261 inline dest_class& dest_class::operator= (const src_class& x)   \
262 {                                                               \
263         /* Be careful, we might be assigning x to itself. */    \
264         cl_uint x_word = x.word;                                \
265         cl_inc_refcount(x);                                     \
266         cl_dec_refcount(*this);                                 \
267         this->word = x_word;                                    \
268         return *this;                                           \
269 }
270
271 // We have a small problem with destructors: The specialized destructor
272 // of a leaf class such as `cl_SF' should be more efficient than the
273 // general destructor for `cl_N'. Since (by C++ specs) destructing a cl_SF
274 // would run the destructors for cl_SF, cl_F, cl_R, cl_N (in that order),
275 // and in the last step the compiler does not know any more that the object
276 // actually is a cl_SF, there is no way to optimize the destructor!
277 // ("progn-reversed" method combination is evil.)
278 // And if we define "mirror"/"shadow" classes with no destructors (such
279 // that `cl_F' inherits from `cl_F_no_destructor' buts adds a destructor)
280 // then we need to add explicit conversion operators cl_SF -> cl_F -> cl_R ...,
281 // with the effect that calling an overloaded function like `as_cl_F'
282 // (which has two signatures `as_cl_F(cl_number)' and `as_cl_F(cl_F)')
283 // with a cl_SF argument gives an "call of overloaded function is ambiguous"
284 // error.
285 // There is no help: If we want overloaded functions to be callable in a way
286 // that makes sense, `cl_SF' has to be a subclass of `cl_F', and then the
287 // destructor of `cl_SF' will do at least as much computation as the `cl_F'
288 // destructor. Praise C++ ! :-((
289 // (Even making `pointer_p()' a virtual function would not help.)
290
291
292 // This is obnoxious.
293 template <class key1_type, class value_type> struct cl_htentry1;
294
295 // The four concrete classes of all objects.
296
297 class cl_gcobject {
298 public: /* ugh */
299         union {
300                 void*   pointer;
301                 cl_heap* heappointer;
302                 cl_uint word;
303         };
304 public:
305 // Default constructor. (Used for objects with no initializer.)
306         cl_gcobject ();
307 // Destructor. (Used when a variable goes out of scope.)
308         ~cl_gcobject ();
309 // Copy constructor.
310         cl_gcobject (const cl_gcobject&);
311 // Assignment operator.
312         cl_gcobject& operator= (const cl_gcobject&);
313 // Distinguish immediate data from pointer.
314         bool pointer_p() const
315                 { return cl_pointer_p(word); }
316 // Reference counting.
317         void inc_pointer_refcount () const
318                 { cl_inc_pointer_refcount(heappointer); }
319         void dec_pointer_refcount () const
320                 { cl_gc_dec_pointer_refcount(heappointer); }
321 // Return the type tag of an immediate number.
322         cl_uint nonpointer_tag () const
323                 { return cl_tag(word); }
324 // Return the type tag of a heap-allocated number.
325         const cl_class * pointer_type () const
326                 { return heappointer->type; }
327 // Private pointer manipulations.
328         cl_private_thing _as_cl_private_thing () const;
329 // Private constructor.
330         cl_gcobject (cl_private_thing p)
331                 : pointer (p) {}
332 // Debugging output.
333         void debug_print () const;
334 // Ability to place an object at a given address.
335         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
336         void* operator new (size_t size) { return ::operator new (size); }
337 };
338 inline cl_gcobject::cl_gcobject () {}
339 inline cl_gcobject::~cl_gcobject () { cl_dec_refcount(*this); }
340 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcobject)
341 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcobject,cl_gcobject)
342
343 class cl_gcpointer {
344 public: /* ugh */
345         union {
346                 void*   pointer;
347                 cl_heap* heappointer;
348                 cl_uint word;
349         };
350 public:
351 // Default constructor. (Used for objects with no initializer.)
352         cl_gcpointer ();
353 // Destructor. (Used when a variable goes out of scope.)
354         ~cl_gcpointer ();
355 // Copy constructor.
356         cl_gcpointer (const cl_gcpointer&);
357 // Assignment operator.
358         cl_gcpointer& operator= (const cl_gcpointer&);
359 // Distinguish immediate data from pointer.
360         bool pointer_p() const
361                 { return true; }
362 // Reference counting.
363         void inc_pointer_refcount () const
364                 { cl_inc_pointer_refcount(heappointer); }
365         void dec_pointer_refcount () const
366                 { cl_gc_dec_pointer_refcount(heappointer); }
367 // Return the type tag of an immediate number.
368         cl_uint nonpointer_tag () const
369                 { return cl_tag(word); }
370 // Return the type tag of a heap-allocated number.
371         const cl_class * pointer_type () const
372                 { return heappointer->type; }
373 // Private pointer manipulations.
374         cl_private_thing _as_cl_private_thing () const;
375 // Private constructor.
376         cl_gcpointer (cl_private_thing p)
377                 : pointer (p) {}
378 // Debugging output.
379         void debug_print () const;
380 // Ability to place an object at a given address.
381         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
382         void* operator new (size_t size) { return ::operator new (size); }
383 };
384 inline cl_gcpointer::cl_gcpointer () {}
385 inline cl_gcpointer::~cl_gcpointer () { cl_dec_refcount(*this); }
386 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcpointer)
387 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcpointer,cl_gcpointer)
388
389 class cl_rcobject {
390 public: /* ugh */
391         union {
392                 void*   pointer;
393                 cl_heap* heappointer;
394                 cl_uint word;
395         };
396 public:
397 // Default constructor. (Used for objects with no initializer.)
398         cl_rcobject ();
399 // Destructor. (Used when a variable goes out of scope.)
400         ~cl_rcobject ();
401 // Copy constructor.
402         cl_rcobject (const cl_rcobject&);
403 // Assignment operator.
404         cl_rcobject& operator= (const cl_rcobject&);
405 // Distinguish immediate data from pointer.
406         bool pointer_p() const
407                 { return cl_pointer_p(word); }
408 // Reference counting.
409         void inc_pointer_refcount () const
410                 { cl_inc_pointer_refcount(heappointer); }
411         void dec_pointer_refcount () const
412                 { cl_rc_dec_pointer_refcount(heappointer); }
413 // Return the type tag of an immediate number.
414         cl_uint nonpointer_tag () const
415                 { return cl_tag(word); }
416 // Return the type tag of a heap-allocated number.
417         const cl_class * pointer_type () const
418                 { return heappointer->type; }
419 // Private pointer manipulations.
420         cl_private_thing _as_cl_private_thing () const;
421 // Private constructor.
422         cl_rcobject (cl_private_thing p)
423                 : pointer (p) {}
424 // Debugging output.
425         void debug_print () const;
426 // Ability to place an object at a given address.
427         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
428         void* operator new (size_t size) { return ::operator new (size); }
429 };
430 inline cl_rcobject::cl_rcobject () {}
431 inline cl_rcobject::~cl_rcobject () { cl_dec_refcount(*this); }
432 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcobject)
433 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcobject,cl_rcobject)
434
435 class cl_rcpointer {
436 public: /* ugh */
437         union {
438                 void*   pointer;
439                 cl_heap* heappointer;
440                 cl_uint word;
441         };
442 public:
443 // Default constructor. (Used for objects with no initializer.)
444         cl_rcpointer ();
445 // Destructor. (Used when a variable goes out of scope.)
446         ~cl_rcpointer ();
447 // Copy constructor.
448         cl_rcpointer (const cl_rcpointer&);
449 // Assignment operator.
450         cl_rcpointer& operator= (const cl_rcpointer&);
451 // Distinguish immediate data from pointer.
452         bool pointer_p() const
453                 { return true; }
454 // Reference counting.
455         void inc_pointer_refcount () const
456                 { cl_inc_pointer_refcount(heappointer); }
457         void dec_pointer_refcount () const
458                 { cl_rc_dec_pointer_refcount(heappointer); }
459 // Return the type tag of an immediate number.
460         cl_uint nonpointer_tag () const
461                 { return cl_tag(word); }
462 // Return the type tag of a heap-allocated number.
463         const cl_class * pointer_type () const
464                 { return heappointer->type; }
465 // Private pointer manipulations.
466         cl_private_thing _as_cl_private_thing () const;
467 // Private constructor.
468         cl_rcpointer (cl_private_thing p)
469                 : pointer (p) {}
470 // Debugging output.
471         void debug_print () const;
472 // Ability to place an object at a given address.
473         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
474         void* operator new (size_t size) { return ::operator new (size); }
475 };
476 inline cl_rcpointer::cl_rcpointer () {}
477 inline cl_rcpointer::~cl_rcpointer () { cl_dec_refcount(*this); }
478 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcpointer)
479 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcpointer,cl_rcpointer)
480
481 // Private pointer manipulations.
482
483 inline cl_private_thing cl_gcobject::_as_cl_private_thing () const
484 {
485         cl_private_thing p = (cl_private_thing) pointer;
486         cl_inc_refcount(*this);
487         return p;
488 }
489 inline cl_private_thing as_cl_private_thing (const cl_gcobject& x)
490 {
491         return x._as_cl_private_thing();
492 }
493
494 inline cl_private_thing cl_gcpointer::_as_cl_private_thing () const
495 {
496         cl_private_thing p = (cl_private_thing) pointer;
497         cl_inc_refcount(*this);
498         return p;
499 }
500 inline cl_private_thing as_cl_private_thing (const cl_gcpointer& x)
501 {
502         return x._as_cl_private_thing();
503 }
504
505 inline cl_private_thing cl_rcobject::_as_cl_private_thing () const
506 {
507         cl_private_thing p = (cl_private_thing) pointer;
508         cl_inc_refcount(*this);
509         return p;
510 }
511 inline cl_private_thing as_cl_private_thing (const cl_rcobject& x)
512 {
513         return x._as_cl_private_thing();
514 }
515
516 inline cl_private_thing cl_rcpointer::_as_cl_private_thing () const
517 {
518         cl_private_thing p = (cl_private_thing) pointer;
519         cl_inc_refcount(*this);
520         return p;
521 }
522 inline cl_private_thing as_cl_private_thing (const cl_rcpointer& x)
523 {
524         return x._as_cl_private_thing();
525 }
526
527 // Note: When we define a function that returns a class object by value,
528 // we normally return it as const value. The declarations
529 //            T func (...);                    (A)
530 // and
531 //            const T func (...);              (B)
532 // behave identically and generate identical code, except that the code
533 //            func(...) = foo;
534 // compiles fine with (A) but is an error (and yields a warning) with (B).
535 // We want this warning.
536
537 // Define a conversion operator from one object to another object of the
538 // same size.
539   #define CL_DEFINE_CONVERTER(target_class)  \
540     operator const target_class & () const                              \
541     {                                                                   \
542       int (*dummy1)(int assert1 [2*(sizeof(target_class)==sizeof(*this))-1]); (void)dummy1; \
543       return * (const target_class *) (void*) this;                     \
544     }
545
546 }  // namespace cln
547
548 #endif /* _CL_OBJECT_H */