]> www.ginac.de Git - cln.git/blob - include/cln/object.h
64-bit mingw port: Avoid ambiguous overload error due to cl_[su]int change.
[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 #ifdef HAVE_LONGLONG
132 inline cl_uint cl_combine (cl_uint tag, unsigned long long value)
133 { return cl_combine_impl(tag, (cl_uint)value); }
134 inline cl_uint cl_combine (cl_uint tag, long long value)
135 { return cl_combine_impl(tag, (cl_uint)value); }
136 #endif
137
138 // Definition of the tags.
139 #if !defined(CL_WIDE_POINTERS)
140   #if (cl_word_alignment == 2)
141     #define cl_FN_tag   1
142     #define cl_SF_tag   3       // must satisfy the cl_immediate_p predicate!
143   #endif
144   #if (cl_word_alignment == 4)
145     #define cl_FN_tag   1
146     #define cl_SF_tag   2
147   #endif
148 #else // CL_WIDE_POINTERS
149   // Single Floats are immediate as well.
150   #define cl_FN_tag     1
151   #define cl_SF_tag     2
152   #define cl_FF_tag     3
153 #endif
154
155 // Corresponding classes.
156 extern const struct cl_class * cl_immediate_classes [1<<cl_tag_len];
157
158
159 // Heap allocated data contains a header, for two purposes:
160 // - dynamic typing,
161 // - reference count (a portable alternative to garbage collection,
162 //   or the basis for a portable and interoperable garbage collection).
163 struct cl_heap {
164         int refcount;                   // reference count
165         const struct cl_class * type;   // type tag
166 };
167
168 // Function to destroy the contents of a heap object.
169 typedef void (*cl_heap_destructor_function) (cl_heap* pointer);
170 // Flags, may be ORed together.
171 #define cl_class_flags_subclass_complex   1  // all instances belong to cl_N
172 #define cl_class_flags_subclass_real      2  // all instances belong to cl_R
173 #define cl_class_flags_subclass_float     4  // all instances belong to cl_F
174 #define cl_class_flags_subclass_rational  8  // all instances belong to cl_RA
175 #define cl_class_flags_number_ring       16  // all instances are rings whose
176                                              // elements belong to cl_number
177 #define cl_class_flags_modint_ring       32  // all instances are rings whose
178                                              // elements belong to cl_MI
179 #define cl_class_flags_univpoly_ring     64  // all instances are rings whose
180                                              // elements belong to cl_UP
181 // Function to print an object for debugging, to cerr.
182 typedef void (*cl_heap_dprint_function) (cl_heap* pointer);
183
184 struct cl_class {
185         cl_heap_destructor_function destruct;
186         int flags;
187         cl_heap_dprint_function dprint;
188 };
189
190 // Free an object on heap.
191 extern void cl_free_heap_object (cl_heap* pointer);
192
193 // Debugging support for dynamic typing: Register a debugging print function.
194 #define cl_register_type_printer(type,printer)  \
195   { extern cl_class type; type.dprint = (printer); }
196
197
198 // cl_private_thing: An immediate value or a pointer into the heap.
199 // This must be as wide as a `cl_uint'.
200 // (Actually, this ought to be a  union { void*; cl_uint; }, but using
201 // a pointer type generates better code.)
202 // Never throw away a cl_private_thing, or reference counts will be wrong!
203 typedef struct cl_anything * cl_private_thing;
204
205 // Increment the reference count.
206 inline void cl_inc_pointer_refcount (cl_heap* pointer)
207 {
208         pointer->refcount++;
209 }
210
211 // Decrement the reference count of a garbage collected pointer.
212 inline void cl_gc_dec_pointer_refcount (cl_heap* pointer)
213 {
214         if (--pointer->refcount == 0)
215                 cl_free_heap_object(pointer);
216 }
217 // Decrement the reference count of a reference counted pointer.
218 inline void cl_rc_dec_pointer_refcount (cl_heap* pointer)
219 {
220         --pointer->refcount;
221 }
222
223 // Increment the reference count.
224 // This must be a macro, not an inline function, because pointer_p() and
225 // inc_pointer_refcount() are non-virtual member functions, so that the
226 // compiler can optimize it.
227 #define cl_inc_refcount(x)  \
228         if ((x).pointer_p())                                    \
229                 (x).inc_pointer_refcount();                     \
230
231 // Decrement the reference count.
232 // This must be a macro, not an inline function, because pointer_p() and
233 // dec_pointer_refcount() are non-virtual member functions, so that the
234 // compiler can optimize it.
235 #define cl_dec_refcount(x)  \
236         if ((x).pointer_p())                                    \
237                 (x).dec_pointer_refcount();                     \
238
239 // The declaration of a copy constructor.
240 // Restriction: The base class's default constructor must do nothing or
241 // initialize `pointer' to a constant expression.
242 #define CL_DEFINE_COPY_CONSTRUCTOR1(_class_)                    \
243         _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_class_)
244 #define _CL_DEFINE_COPY_CONSTRUCTOR1(_class_,_classname_)       \
245 inline _class_::_classname_ (const _class_& x)                  \
246 {                                                               \
247         cl_uint x_word = x.word;                                \
248         cl_inc_refcount(x);                                     \
249         this->word = x_word;                                    \
250 }
251
252 // The declaration of a copy constructor.
253 // Restriction: The base class must have the usual `cl_private_thing'
254 // constructor. Drawback: The base class must be known here.
255 #define CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_baseclass_)                \
256         _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_class_,_baseclass_)
257 #define _CL_DEFINE_COPY_CONSTRUCTOR2(_class_,_classname_,_baseclass_) \
258 inline _class_::_classname_ (const _class_& x)                  \
259         : _baseclass_ (as_cl_private_thing(x)) {}
260
261 // The declaration of an assignment operator.
262 #define CL_DEFINE_ASSIGNMENT_OPERATOR(dest_class,src_class)     \
263 inline dest_class& dest_class::operator= (const src_class& x)   \
264 {                                                               \
265         /* Be careful, we might be assigning x to itself. */    \
266         cl_uint x_word = x.word;                                \
267         cl_inc_refcount(x);                                     \
268         cl_dec_refcount(*this);                                 \
269         this->word = x_word;                                    \
270         return *this;                                           \
271 }
272
273 // We have a small problem with destructors: The specialized destructor
274 // of a leaf class such as `cl_SF' should be more efficient than the
275 // general destructor for `cl_N'. Since (by C++ specs) destructing a cl_SF
276 // would run the destructors for cl_SF, cl_F, cl_R, cl_N (in that order),
277 // and in the last step the compiler does not know any more that the object
278 // actually is a cl_SF, there is no way to optimize the destructor!
279 // ("progn-reversed" method combination is evil.)
280 // And if we define "mirror"/"shadow" classes with no destructors (such
281 // that `cl_F' inherits from `cl_F_no_destructor' buts adds a destructor)
282 // then we need to add explicit conversion operators cl_SF -> cl_F -> cl_R ...,
283 // with the effect that calling an overloaded function like `as_cl_F'
284 // (which has two signatures `as_cl_F(cl_number)' and `as_cl_F(cl_F)')
285 // with a cl_SF argument gives an "call of overloaded function is ambiguous"
286 // error.
287 // There is no help: If we want overloaded functions to be callable in a way
288 // that makes sense, `cl_SF' has to be a subclass of `cl_F', and then the
289 // destructor of `cl_SF' will do at least as much computation as the `cl_F'
290 // destructor. Praise C++ ! :-((
291 // (Even making `pointer_p()' a virtual function would not help.)
292
293
294 // This is obnoxious.
295 template <class key1_type, class value_type> struct cl_htentry1;
296
297 // The four concrete classes of all objects.
298
299 class cl_gcobject {
300 public: /* ugh */
301         union {
302                 void*   pointer;
303                 cl_heap* heappointer;
304                 cl_uint word;
305         };
306 public:
307 // Default constructor. (Used for objects with no initializer.)
308         cl_gcobject ();
309 // Destructor. (Used when a variable goes out of scope.)
310         ~cl_gcobject ();
311 // Copy constructor.
312         cl_gcobject (const cl_gcobject&);
313 // Assignment operator.
314         cl_gcobject& operator= (const cl_gcobject&);
315 // Distinguish immediate data from pointer.
316         bool pointer_p() const
317                 { return cl_pointer_p(word); }
318 // Reference counting.
319         void inc_pointer_refcount () const
320                 { cl_inc_pointer_refcount(heappointer); }
321         void dec_pointer_refcount () const
322                 { cl_gc_dec_pointer_refcount(heappointer); }
323 // Return the type tag of an immediate number.
324         cl_uint nonpointer_tag () const
325                 { return cl_tag(word); }
326 // Return the type tag of a heap-allocated number.
327         const cl_class * pointer_type () const
328                 { return heappointer->type; }
329 // Private pointer manipulations.
330         cl_private_thing _as_cl_private_thing () const;
331 // Private constructor.
332         cl_gcobject (cl_private_thing p)
333                 : pointer (p) {}
334 // Debugging output.
335         void debug_print () const;
336 // Ability to place an object at a given address.
337         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
338         void* operator new (size_t size) { return ::operator new (size); }
339 };
340 inline cl_gcobject::cl_gcobject () {}
341 inline cl_gcobject::~cl_gcobject () { cl_dec_refcount(*this); }
342 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcobject)
343 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcobject,cl_gcobject)
344
345 class cl_gcpointer {
346 public: /* ugh */
347         union {
348                 void*   pointer;
349                 cl_heap* heappointer;
350                 cl_uint word;
351         };
352 public:
353 // Default constructor. (Used for objects with no initializer.)
354         cl_gcpointer ();
355 // Destructor. (Used when a variable goes out of scope.)
356         ~cl_gcpointer ();
357 // Copy constructor.
358         cl_gcpointer (const cl_gcpointer&);
359 // Assignment operator.
360         cl_gcpointer& operator= (const cl_gcpointer&);
361 // Distinguish immediate data from pointer.
362         bool pointer_p() const
363                 { return true; }
364 // Reference counting.
365         void inc_pointer_refcount () const
366                 { cl_inc_pointer_refcount(heappointer); }
367         void dec_pointer_refcount () const
368                 { cl_gc_dec_pointer_refcount(heappointer); }
369 // Return the type tag of an immediate number.
370         cl_uint nonpointer_tag () const
371                 { return cl_tag(word); }
372 // Return the type tag of a heap-allocated number.
373         const cl_class * pointer_type () const
374                 { return heappointer->type; }
375 // Private pointer manipulations.
376         cl_private_thing _as_cl_private_thing () const;
377 // Private constructor.
378         cl_gcpointer (cl_private_thing p)
379                 : pointer (p) {}
380 // Debugging output.
381         void debug_print () const;
382 // Ability to place an object at a given address.
383         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
384         void* operator new (size_t size) { return ::operator new (size); }
385 };
386 inline cl_gcpointer::cl_gcpointer () {}
387 inline cl_gcpointer::~cl_gcpointer () { cl_dec_refcount(*this); }
388 CL_DEFINE_COPY_CONSTRUCTOR1(cl_gcpointer)
389 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_gcpointer,cl_gcpointer)
390
391 class cl_rcobject {
392 public: /* ugh */
393         union {
394                 void*   pointer;
395                 cl_heap* heappointer;
396                 cl_uint word;
397         };
398 public:
399 // Default constructor. (Used for objects with no initializer.)
400         cl_rcobject ();
401 // Destructor. (Used when a variable goes out of scope.)
402         ~cl_rcobject ();
403 // Copy constructor.
404         cl_rcobject (const cl_rcobject&);
405 // Assignment operator.
406         cl_rcobject& operator= (const cl_rcobject&);
407 // Distinguish immediate data from pointer.
408         bool pointer_p() const
409                 { return cl_pointer_p(word); }
410 // Reference counting.
411         void inc_pointer_refcount () const
412                 { cl_inc_pointer_refcount(heappointer); }
413         void dec_pointer_refcount () const
414                 { cl_rc_dec_pointer_refcount(heappointer); }
415 // Return the type tag of an immediate number.
416         cl_uint nonpointer_tag () const
417                 { return cl_tag(word); }
418 // Return the type tag of a heap-allocated number.
419         const cl_class * pointer_type () const
420                 { return heappointer->type; }
421 // Private pointer manipulations.
422         cl_private_thing _as_cl_private_thing () const;
423 // Private constructor.
424         cl_rcobject (cl_private_thing p)
425                 : pointer (p) {}
426 // Debugging output.
427         void debug_print () const;
428 // Ability to place an object at a given address.
429         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
430         void* operator new (size_t size) { return ::operator new (size); }
431 };
432 inline cl_rcobject::cl_rcobject () {}
433 inline cl_rcobject::~cl_rcobject () { cl_dec_refcount(*this); }
434 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcobject)
435 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcobject,cl_rcobject)
436
437 class cl_rcpointer {
438 public: /* ugh */
439         union {
440                 void*   pointer;
441                 cl_heap* heappointer;
442                 cl_uint word;
443         };
444 public:
445 // Default constructor. (Used for objects with no initializer.)
446         cl_rcpointer ();
447 // Destructor. (Used when a variable goes out of scope.)
448         ~cl_rcpointer ();
449 // Copy constructor.
450         cl_rcpointer (const cl_rcpointer&);
451 // Assignment operator.
452         cl_rcpointer& operator= (const cl_rcpointer&);
453 // Distinguish immediate data from pointer.
454         bool pointer_p() const
455                 { return true; }
456 // Reference counting.
457         void inc_pointer_refcount () const
458                 { cl_inc_pointer_refcount(heappointer); }
459         void dec_pointer_refcount () const
460                 { cl_rc_dec_pointer_refcount(heappointer); }
461 // Return the type tag of an immediate number.
462         cl_uint nonpointer_tag () const
463                 { return cl_tag(word); }
464 // Return the type tag of a heap-allocated number.
465         const cl_class * pointer_type () const
466                 { return heappointer->type; }
467 // Private pointer manipulations.
468         cl_private_thing _as_cl_private_thing () const;
469 // Private constructor.
470         cl_rcpointer (cl_private_thing p)
471                 : pointer (p) {}
472 // Debugging output.
473         void debug_print () const;
474 // Ability to place an object at a given address.
475         void* operator new (size_t size, void* ptr) { (void)size; return ptr; }
476         void* operator new (size_t size) { return ::operator new (size); }
477 };
478 inline cl_rcpointer::cl_rcpointer () {}
479 inline cl_rcpointer::~cl_rcpointer () { cl_dec_refcount(*this); }
480 CL_DEFINE_COPY_CONSTRUCTOR1(cl_rcpointer)
481 CL_DEFINE_ASSIGNMENT_OPERATOR(cl_rcpointer,cl_rcpointer)
482
483 // Private pointer manipulations.
484
485 inline cl_private_thing cl_gcobject::_as_cl_private_thing () const
486 {
487         cl_private_thing p = (cl_private_thing) pointer;
488         cl_inc_refcount(*this);
489         return p;
490 }
491 inline cl_private_thing as_cl_private_thing (const cl_gcobject& x)
492 {
493         return x._as_cl_private_thing();
494 }
495
496 inline cl_private_thing cl_gcpointer::_as_cl_private_thing () const
497 {
498         cl_private_thing p = (cl_private_thing) pointer;
499         cl_inc_refcount(*this);
500         return p;
501 }
502 inline cl_private_thing as_cl_private_thing (const cl_gcpointer& x)
503 {
504         return x._as_cl_private_thing();
505 }
506
507 inline cl_private_thing cl_rcobject::_as_cl_private_thing () const
508 {
509         cl_private_thing p = (cl_private_thing) pointer;
510         cl_inc_refcount(*this);
511         return p;
512 }
513 inline cl_private_thing as_cl_private_thing (const cl_rcobject& x)
514 {
515         return x._as_cl_private_thing();
516 }
517
518 inline cl_private_thing cl_rcpointer::_as_cl_private_thing () const
519 {
520         cl_private_thing p = (cl_private_thing) pointer;
521         cl_inc_refcount(*this);
522         return p;
523 }
524 inline cl_private_thing as_cl_private_thing (const cl_rcpointer& x)
525 {
526         return x._as_cl_private_thing();
527 }
528
529 // Note: When we define a function that returns a class object by value,
530 // we normally return it as const value. The declarations
531 //            T func (...);                    (A)
532 // and
533 //            const T func (...);              (B)
534 // behave identically and generate identical code, except that the code
535 //            func(...) = foo;
536 // compiles fine with (A) but is an error (and yields a warning) with (B).
537 // We want this warning.
538
539 // Define a conversion operator from one object to another object of the
540 // same size.
541   #define CL_DEFINE_CONVERTER(target_class)  \
542     operator const target_class & () const                              \
543     {                                                                   \
544       int (*dummy1)(int assert1 [2*(sizeof(target_class)==sizeof(*this))-1]); (void)dummy1; \
545       return * (const target_class *) (void*) this;                     \
546     }
547
548 }  // namespace cln
549
550 #endif /* _CL_OBJECT_H */