1 /****************************************************************************
2 **
3 ** This file is part of GAP, a system for computational discrete algebra.
4 **
5 ** Copyright of GAP belongs to its developers, whose names are too numerous
6 ** to list here. Please refer to the COPYRIGHT file for details.
7 **
8 ** SPDX-License-Identifier: GPL-2.0-or-later
9 **
10 ** This file defines the functions of the objects package.
11 **
12 ** The objects package is the part that defines the 'Obj' type, the objects
13 ** types (i.e., the numbers that Gasman needs to distinguish types), the
14 ** dispatcher for the printing of objects, etc.
15 */
16
17 #ifndef GAP_OBJECTS_H
18 #define GAP_OBJECTS_H
19
20 #include "gasman.h"
21 #include "intobj.h"
22
23 #ifdef HPCGAP
24 #define USE_THREADSAFE_COPYING
25 #endif
26
27
28 /****************************************************************************
29 **
30 *t Obj . . . . . . . . . . . . . . . . . . . . . . . . . . . type of objects
31 **
32 ** 'Obj' is the type of objects.
33 **
34 ** The following is defined in "system.h"
35 **
36 #define Obj Bag
37 */
38
39
40 /****************************************************************************
41 **
42 *F IS_FFE( <o> ) . . . . . . . . test if an object is a finite field element
43 **
44 ** 'IS_FFE' returns 1 if the object <o> is an (immediate) finite field
45 ** element and 0 otherwise.
46 */
IS_FFE(Obj o)47 EXPORT_INLINE Int IS_FFE(Obj o)
48 {
49 return (Int)o & 0x02;
50 }
51
52
53 /****************************************************************************
54 **
55 *F RegisterPackageTNUM( <name>, <typeObjFunc> )
56 **
57 ** Allocates a TNUM for use by a package. The parameters <name> and
58 ** <typeObjFunc> are used to initialize the relevant entries in the
59 ** InfoBags and TypeObjFuncs arrays.
60 **
61 ** If allocation fails (e.g. because no more TNUMs are available),
62 ** a negative value is returned.
63 */
64 Int RegisterPackageTNUM(const char * name, Obj (*typeObjFunc)(Obj obj));
65
66
67 /****************************************************************************
68 **
69 *F NEXT_ENUM_EVEN( <id> )
70 *F START_ENUM_RANGE_EVEN( <id> )
71 *F END_ENUM_RANGE_ODD( <id> )
72 **
73 ** 'NEXT_ENUM_EVEN' can be used in an enum to force <id> to use the next
74 ** available even integer value.
75 **
76 ** 'START_ENUM_RANGE_EVEN' is a variant of 'START_ENUM_RANGE' which always
77 ** sets the value of <id> to the next even integer.
78 **
79 ** 'END_ENUM_RANGE_ODD' is a variant of 'END_ENUM_RANGE' which always sets
80 ** the value of <id> to an odd integer.
81 */
82 #define NEXT_ENUM_EVEN(id) \
83 _##id##_pre, \
84 id = _##id##_pre + (_##id##_pre & 1)
85 #define START_ENUM_RANGE_EVEN(id) \
86 NEXT_ENUM_EVEN(id), \
87 _##id##_post = id - 1
88 #define END_ENUM_RANGE_ODD(id) \
89 _##id##_pre, \
90 id = _##id##_pre - !(_##id##_pre & 1)
91
92
93 /****************************************************************************
94 **
95 */
96 enum {
97 IMMUTABLE = 1 // IMMUTABLE is not a TNUM, but rather a bitmask
98 };
99
100 /****************************************************************************
101 **
102 *S T_<name> . . . . . . . . . . . . . . . . symbolic names for object types
103 *S FIRST_CONSTANT_TNUM, LAST_CONSTANT_TNUM . . . . range of constant types
104 *S FIRST_RECORD_TNUM, LAST_RECORD_TNUM . . . . . range of record types
105 *S FIRST_LIST_TNUM, LAST_LIST_TNUM . . . . . . range of list types
106 *S FIRST_EXTERNAL_TNUM, LAST_EXTERNAL_TNUM . . . . range of external types
107 *S FIRST_REAL_TNUM, LAST_REAL_TNUM . . . . . . range of real types
108 *S FIRST_IMM_MUT_TNUM, LAST_IMM_MUT_TNUM . . . . range of im/mutable types
109 **
110 ** For every type of objects there is a symbolic name defined for this type.
111 **
112 ** 'FIRST_CONSTANT_TNUM' is the first type of constant objects, e.g.,
113 ** integers, booleans, and functions. 'LAST_CONSTANT_TNUM' is the last type
114 ** of constant objects.
115 **
116 ** 'FIRST_RECORD_TNUM' is the first type of record objects, currently only
117 ** plain records. 'LAST_RECORD_TNUM' is the last type of record objects.
118 **
119 ** 'FIRST_LIST_TNUM' is the first type of list objects, e.g., plain lists,
120 ** ranges, boolean lists, and strings. 'LAST_LIST_TNUM' is the last type of
121 ** list objects.
122 **
123 ** 'FIRST_EXTERNAL_TNUM' is the first type of external objects, currently
124 ** only component objects, positional objects, and data objects.
125 ** 'LAST_EXTERNAL_TNUM' is the last type of external objects.
126 **
127 ** 'FIRST_REAL_TNUM' is the first real type, namely 'FIRST_CONSTANT_TNUM'.
128 ** 'LAST_REAL_TNUM' is the last real type, namely 'LAST_EXTERNAL_TNUM'.
129 **
130 ** 'FIRST_IMM_MUT_TNUM' is the first real internal type of objects which
131 ** might be mutable, 'LAST_IMM_MUT_TNUM' is the last such type.
132 **
133 ** The types *must* be sorted in this order, i.e., first the constant types,
134 ** then the record types, then the list types, then the external types, and
135 ** finally the virtual types.
136 */
137 enum TNUM {
138 START_ENUM_RANGE(FIRST_REAL_TNUM),
139
140 START_ENUM_RANGE(FIRST_CONSTANT_TNUM),
141
142 // The next range contains all constant TNUMs for which multiplication
143 // with an integer resp. powering by an integer makes sense
144 START_ENUM_RANGE(FIRST_MULT_TNUM),
145 T_INT, // immediate
146 T_INTPOS,
147 T_INTNEG,
148 T_RAT,
149 T_CYC,
150 T_FFE, // immediate
151 T_MACFLOAT,
152 T_PERM2,
153 T_PERM4,
154 T_TRANS2,
155 T_TRANS4,
156 T_PPERM2,
157 T_PPERM4,
158 END_ENUM_RANGE(LAST_MULT_TNUM),
159
160 T_BOOL,
161 T_CHAR,
162
163 T_FUNCTION,
164 T_BODY, // the type of function body bags
165 T_FLAGS,
166 T_LVARS,
167 T_HVARS,
168 END_ENUM_RANGE(LAST_CONSTANT_TNUM),
169
170 // first mutable/immutable TNUM
171 START_ENUM_RANGE_EVEN(FIRST_IMM_MUT_TNUM),
172
173 // records
174 START_ENUM_RANGE_EVEN(FIRST_RECORD_TNUM),
175 T_PREC,
176 END_ENUM_RANGE_ODD(LAST_RECORD_TNUM),
177
178 // lists
179 START_ENUM_RANGE_EVEN(FIRST_LIST_TNUM),
180
181 // plists
182 START_ENUM_RANGE_EVEN(FIRST_PLIST_TNUM),
183 NEXT_ENUM_EVEN(T_PLIST),
184 NEXT_ENUM_EVEN(T_PLIST_NDENSE),
185 NEXT_ENUM_EVEN(T_PLIST_DENSE),
186 NEXT_ENUM_EVEN(T_PLIST_DENSE_NHOM),
187 NEXT_ENUM_EVEN(T_PLIST_DENSE_NHOM_SSORT),
188 NEXT_ENUM_EVEN(T_PLIST_DENSE_NHOM_NSORT),
189 NEXT_ENUM_EVEN(T_PLIST_EMPTY),
190 NEXT_ENUM_EVEN(T_PLIST_HOM),
191 NEXT_ENUM_EVEN(T_PLIST_HOM_NSORT),
192 NEXT_ENUM_EVEN(T_PLIST_HOM_SSORT),
193 NEXT_ENUM_EVEN(T_PLIST_TAB),
194 NEXT_ENUM_EVEN(T_PLIST_TAB_NSORT),
195 NEXT_ENUM_EVEN(T_PLIST_TAB_SSORT),
196 NEXT_ENUM_EVEN(T_PLIST_TAB_RECT),
197 NEXT_ENUM_EVEN(T_PLIST_TAB_RECT_NSORT),
198 NEXT_ENUM_EVEN(T_PLIST_TAB_RECT_SSORT),
199 NEXT_ENUM_EVEN(T_PLIST_CYC),
200 NEXT_ENUM_EVEN(T_PLIST_CYC_NSORT),
201 NEXT_ENUM_EVEN(T_PLIST_CYC_SSORT),
202 NEXT_ENUM_EVEN(T_PLIST_FFE),
203 END_ENUM_RANGE_ODD(LAST_PLIST_TNUM),
204
205 // other kinds of lists
206 NEXT_ENUM_EVEN(T_RANGE_NSORT),
207 NEXT_ENUM_EVEN(T_RANGE_SSORT),
208 NEXT_ENUM_EVEN(T_BLIST),
209 NEXT_ENUM_EVEN(T_BLIST_NSORT),
210 NEXT_ENUM_EVEN(T_BLIST_SSORT),
211 NEXT_ENUM_EVEN(T_STRING),
212 NEXT_ENUM_EVEN(T_STRING_NSORT),
213 NEXT_ENUM_EVEN(T_STRING_SSORT),
214
215 END_ENUM_RANGE_ODD(LAST_LIST_TNUM),
216
217 // object sets and maps
218 START_ENUM_RANGE_EVEN(FIRST_OBJSET_TNUM),
219 NEXT_ENUM_EVEN(T_OBJSET),
220 NEXT_ENUM_EVEN(T_OBJMAP),
221 END_ENUM_RANGE_ODD(LAST_OBJSET_TNUM),
222
223 // last mutable/immutable TNUM
224 END_ENUM_RANGE(LAST_IMM_MUT_TNUM),
225
226 // external types
227 START_ENUM_RANGE(FIRST_EXTERNAL_TNUM),
228 T_COMOBJ,
229 T_POSOBJ,
230 T_DATOBJ,
231 T_WPOBJ,
232 #ifdef HPCGAP
233 T_ACOMOBJ,
234 T_APOSOBJ,
235 #endif
236
237 // package TNUMs, for use by kernel extensions
238 //
239 // The value of LAST_REAL_TNUM must not exceed 254.
240 // This restricts the value for LAST_PACKAGE_TNUM indirectly. It is
241 // difficult to describe the largest possible value with a formula,
242 // as LAST_REAL_TNUM itself changes depending LAST_PACKAGE_TNUM, and
243 // the fact that some TNUMs are forced to be even causes additional
244 // jumps; increasing LAST_PACKAGE_TNUM by 1 can lead to
245 // LAST_REAL_TNUM growing by 2. So we simply hand-pick
246 // LAST_PACKAGE_TNUM as the largest value that does not trigger the
247 // GAP_STATIC_ASSERT following this enum.
248 FIRST_PACKAGE_TNUM,
249 #ifdef HPCGAP
250 LAST_PACKAGE_TNUM = FIRST_PACKAGE_TNUM + 153,
251 #else
252 LAST_PACKAGE_TNUM = FIRST_PACKAGE_TNUM + 167,
253 #endif
254
255 END_ENUM_RANGE(LAST_EXTERNAL_TNUM),
256
257 #ifdef HPCGAP
258 START_ENUM_RANGE(FIRST_SHARED_TNUM),
259 // primitive types
260 T_THREAD,
261 T_MONITOR,
262 T_REGION,
263 // user-programmable types
264 T_SEMAPHORE,
265 T_CHANNEL,
266 T_BARRIER,
267 T_SYNCVAR,
268 // atomic lists and records, thread local records
269 START_ENUM_RANGE(FIRST_ATOMIC_TNUM),
270 START_ENUM_RANGE(FIRST_ATOMIC_LIST_TNUM),
271 T_FIXALIST,
272 T_ALIST,
273 END_ENUM_RANGE(LAST_ATOMIC_LIST_TNUM),
274 START_ENUM_RANGE(FIRST_ATOMIC_RECORD_TNUM),
275 T_AREC,
276 T_AREC_INNER,
277 T_TLREC,
278 T_TLREC_INNER,
279 END_ENUM_RANGE(LAST_ATOMIC_RECORD_TNUM),
280 END_ENUM_RANGE(LAST_ATOMIC_TNUM),
281 END_ENUM_RANGE(LAST_SHARED_TNUM),
282 #endif
283
284 END_ENUM_RANGE(LAST_REAL_TNUM),
285
286 #if !defined(USE_THREADSAFE_COPYING)
287 T_COPYING,
288 #endif
289 };
290
291 #if !defined(USE_THREADSAFE_COPYING)
292 GAP_STATIC_ASSERT(T_COPYING <= 254, "T_COPYING is too large");
293 #else
294 GAP_STATIC_ASSERT(LAST_REAL_TNUM <= 254, "LAST_REAL_TNUM is too large");
295 #endif
296
297
298 /****************************************************************************
299 **
300 *F TEST_OBJ_FLAG(<obj>, <flag>) . . . . . . . . . . . . . . test object flag
301 *F SET_OBJ_FLAG(<obj>, <flag>) . . . . . . . . . . . . . . . set object flag
302 *F CLEAR_OBJ_FLAG(<obj>, <flag>) . . . . . . . . . . . . . clear object flag
303 **
304 ** These three functions test, set, and clear object flags, respectively.
305 ** For non-immediate objects, these are simply the bag flags, see
306 ** TEST_BAG_FLAG, SET_BAG_FLAG, CLEAR_BAG_FLAG.
307 **
308 ** For immediate objects, objects flags are always 0.
309 */
TEST_OBJ_FLAG(Obj obj,uint8_t flag)310 EXPORT_INLINE uint8_t TEST_OBJ_FLAG(Obj obj, uint8_t flag)
311 {
312 if (IS_BAG_REF(obj))
313 return TEST_BAG_FLAG(obj, flag);
314 else
315 return 0;
316 }
317
SET_OBJ_FLAG(Obj obj,uint8_t flag)318 EXPORT_INLINE void SET_OBJ_FLAG(Obj obj, uint8_t flag)
319 {
320 if (IS_BAG_REF(obj))
321 SET_BAG_FLAG(obj, flag);
322 }
323
CLEAR_OBJ_FLAG(Obj obj,uint8_t flag)324 EXPORT_INLINE void CLEAR_OBJ_FLAG(Obj obj, uint8_t flag)
325 {
326 if (IS_BAG_REF(obj))
327 CLEAR_BAG_FLAG(obj, flag);
328 }
329
330
331 /****************************************************************************
332 **
333 ** Object flags for use with SET_OBJ_FLAG() etc.
334 **
335 */
336 enum {
337 TESTING = (1 << 0),
338 #ifdef HPCGAP
339 TESTED = (1 << 1),
340 #endif
341 };
342
343
344 /****************************************************************************
345 **
346 *F TNUM_OBJ( <obj> ) . . . . . . . . . . . . . . . . . . . type of an object
347 **
348 ** 'TNUM_OBJ' returns the type of the object <obj>.
349 */
TNUM_OBJ(Obj obj)350 EXPORT_INLINE UInt TNUM_OBJ(Obj obj)
351 {
352 if (IS_INTOBJ(obj))
353 return T_INT;
354 if (IS_FFE(obj))
355 return T_FFE;
356 return TNUM_BAG(obj);
357 }
358
359
360 /****************************************************************************
361 **
362 *F TNAM_TNUM( <obj> ) . . . . . . . . . . . . . . . . . . . . name of a type
363 */
364 const Char * TNAM_TNUM(UInt tnum);
365
366
367 /****************************************************************************
368 **
369 *F SET_TNAM_TNUM( <obj> ) . . . . . . . . . . . . . . set the name of a type
370 */
371 void SET_TNAM_TNUM(UInt tnum, const Char * name);
372
373
374 /****************************************************************************
375 **
376 *F TNAM_OBJ( <obj> ) . . . . . . . . . . . . . name of the type of an object
377 */
TNAM_OBJ(Obj obj)378 EXPORT_INLINE const Char * TNAM_OBJ(Obj obj)
379 {
380 return TNAM_TNUM(TNUM_OBJ(obj));
381 }
382
383
384 /****************************************************************************
385 **
386 *F SIZE_OBJ( <obj> ) . . . . . . . . . . . . . . . . . . . size of an object
387 **
388 ** 'SIZE_OBJ' returns the size of the object <obj>.
389 */
SIZE_OBJ(Obj obj)390 EXPORT_INLINE UInt SIZE_OBJ(Obj obj)
391 {
392 return SIZE_BAG(obj);
393 }
394
395
396 /****************************************************************************
397 **
398 *F ADDR_OBJ( <obj> ) . . . . . . . . . . . . . absolute address of an object
399 **
400 ** 'ADDR_OBJ' returns the absolute address of the memory block of the object
401 ** <obj>.
402 */
ADDR_OBJ(Obj obj)403 EXPORT_INLINE Obj *ADDR_OBJ(Obj obj)
404 {
405 return PTR_BAG(obj);
406 }
407
CONST_ADDR_OBJ(Obj obj)408 EXPORT_INLINE const Obj *CONST_ADDR_OBJ(Obj obj)
409 {
410 return CONST_PTR_BAG(obj);
411 }
412
413
414 /****************************************************************************
415 **
416 *S POS_FAMILY_TYPE . . . . . . position where the family of a type is stored
417 *S POS_FLAGS_TYPE . . . . . . position where the flags of a type are stored
418 *S POS_DATA_TYPE . . . . . . . . position where the data of a type is stored
419 *S POS_NUMB_TYPE . . . . . . . position where the number of a type is stored
420 *S POS_FIRST_FREE_TYPE . . . . . first position that has no overall meaning
421 */
422 enum {
423 POS_FAMILY_TYPE = 1,
424 POS_FLAGS_TYPE = 2,
425 POS_DATA_TYPE = 3,
426 POS_NUMB_TYPE = 4,
427 POS_FIRST_FREE_TYPE = 5,
428 };
429
430
431 /****************************************************************************
432 **
433 *F FAMILY_TYPE( <type> ) . . . . . . . . . . . . . . . . . family of a type
434 **
435 ** 'FAMILY_TYPE' returns the family of the type <type>.
436 */
437 #define FAMILY_TYPE(type) ELM_PLIST( type, POS_FAMILY_TYPE )
438
439
440 /****************************************************************************
441 **
442 *F FAMILY_OBJ( <obj> ) . . . . . . . . . . . . . . . . . family of an object
443 */
444 #define FAMILY_OBJ(obj) FAMILY_TYPE( TYPE_OBJ(obj) )
445
446
447 /****************************************************************************
448 **
449 *F FLAGS_TYPE( <type> ) . . . . . . . . . . . . flags boolean list of a type
450 **
451 ** 'FLAGS_TYPE' returns the flags boolean list of the type <type>.
452 */
453 #define FLAGS_TYPE(type) ELM_PLIST( type, POS_FLAGS_TYPE )
454
455
456 /****************************************************************************
457 **
458 *F DATA_TYPE( <type> ) . . . . . . . . . . . . . . . . shared data of a type
459 **
460 ** 'DATA_TYPE' returns the shared data of the type <type>.
461 ** Not used by the GAP kernel right now, but useful for kernel extensions.
462 */
463 #define DATA_TYPE(type) ELM_PLIST( type, POS_DATA_TYPE )
464
465
466 /****************************************************************************
467 **
468 *F ID_TYPE( <type> ) . . . . . . . . . . . . . . . . . . . . . id of a type
469 **
470 ** 'ID_TYPE' returns the ID of a type. Warning: if GAP runs out of ID it
471 ** will renumber all IDs. Therefore the corresponding routine must excatly
472 ** know where such numbers are stored.
473 */
474 #define ID_TYPE(type) ELM_PLIST(type, POS_NUMB_TYPE)
475 #define SET_ID_TYPE(type, val) SET_ELM_PLIST(type, POS_NUMB_TYPE, val)
476
477
478 /****************************************************************************
479 **
480 *F TYPE_OBJ( <obj> ) . . . . . . . . . . . . . . . . . . . type of an object
481 **
482 ** 'TYPE_OBJ' returns the type of the object <obj>.
483 */
484 extern Obj (*TypeObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
TYPE_OBJ(Obj obj)485 EXPORT_INLINE Obj TYPE_OBJ(Obj obj)
486 {
487 UInt tnum = TNUM_OBJ(obj);
488 return (*TypeObjFuncs[tnum])(obj);
489 }
490
491
492 /****************************************************************************
493 **
494 *F SET_TYPE_OBJ( <obj>, <kind> ) . . . . . . . . . . . set kind of an object
495 **
496 ** 'SET_TYPE_OBJ' sets the kind <kind>of the object <obj>.
497 */
498 extern void (*SetTypeObjFuncs[ LAST_REAL_TNUM+1 ]) ( Obj obj, Obj kind );
SET_TYPE_OBJ(Obj obj,Obj type)499 EXPORT_INLINE void SET_TYPE_OBJ(Obj obj, Obj type)
500 {
501 UInt tnum = TNUM_OBJ(obj);
502 (*SetTypeObjFuncs[tnum])(obj, type);
503 }
504
505
506 /****************************************************************************
507 **
508 *F MUTABLE_TNUM( <type> ) . . . . . . . . . . mutable type of internal type
509 */
510 #define MUTABLE_TNUM(type) \
511 ( ( (type) < FIRST_IMM_MUT_TNUM ? (type) : \
512 ( LAST_IMM_MUT_TNUM < (type) ? (type) : \
513 ( ((((type)-T_PLIST)&(~IMMUTABLE))+T_PLIST) ) ) ) )
514
515
516 /****************************************************************************
517 **
518 *F IMMUTABLE_TNUM( <type> ) . . . . . . . . immutable type of internal type
519 */
520 #define IMMUTABLE_TNUM(type) \
521 ( ( (type) < FIRST_IMM_MUT_TNUM ? (type) : \
522 ( LAST_IMM_MUT_TNUM < (type) ? (type) : \
523 ( ((((type)-T_PLIST)|IMMUTABLE)+T_PLIST) ) ) ) )
524
525 /****************************************************************************
526 **
527 *F MakeImmutable( <obj> ) . . . . . . . . . . . . . make an object immutable
528 */
529 void MakeImmutable(Obj obj);
530
531
532 /****************************************************************************
533 **
534 *F MakeImmutableNoRecurse( <obj> ) . . set immutable flag on internal object
535 **
536 ** This is an unsafe helper function, for use in functions installed as
537 ** handlers in 'MakeImmutableObjFuncs' for internal objects tracking their
538 ** mutability, i.e., in the range FIRST_IMM_MUT_TNUM to LAST_IMM_MUT_TNUM.
539 ** It only modifies the TNUM, and does not make subobjects immutable.
540 */
MakeImmutableNoRecurse(Obj obj)541 EXPORT_INLINE void MakeImmutableNoRecurse(Obj obj)
542 {
543 UInt type = TNUM_OBJ(obj);
544 GAP_ASSERT((FIRST_IMM_MUT_TNUM <= type) && (type <= LAST_IMM_MUT_TNUM));
545 RetypeBag(obj, type | IMMUTABLE);
546 }
547
548
549 /****************************************************************************
550 **
551 *F CheckedMakeImmutable( <obj> ) . . . . . . . . . make an object immutable
552 **
553 ** Same effect as MakeImmutable( <obj> ), but checks first that all
554 ** subobjects lie in a writable region.
555 */
556
557 #ifdef HPCGAP
558 void CheckedMakeImmutable(Obj obj);
559 #endif
560
561 /****************************************************************************
562 **
563 *F IS_MUTABLE_OBJ( <obj> ) . . . . . . . . . . . . . . is an object mutable
564 **
565 ** 'IS_MUTABLE_OBJ' returns 1 if the object <obj> is mutable (i.e., can
566 ** change due to assignments), and 0 otherwise.
567 */
568 extern Int (*IsMutableObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
IS_MUTABLE_OBJ(Obj obj)569 EXPORT_INLINE Int IS_MUTABLE_OBJ(Obj obj)
570 {
571 UInt tnum = TNUM_OBJ(obj);
572 if (/*FIRST_CONSTANT_TNUM <= tnum &&*/ tnum <= LAST_CONSTANT_TNUM)
573 return 0;
574 if (FIRST_IMM_MUT_TNUM <= tnum && tnum <= LAST_IMM_MUT_TNUM)
575 return !(tnum & IMMUTABLE);
576 return ((*IsMutableObjFuncs[tnum])(obj));
577 }
578
579
580 /****************************************************************************
581 **
582 *F IsInternallyMutableObj( <obj> ) . . . does an object have a mutable state
583 **
584 ** This function returns 1 if the object <obj> has a mutable state, i.e.
585 ** if its internal representation can change even though its outwardly
586 ** visible properties do not, e.g. through code that transparently
587 ** reorganizes its structure.
588 */
589
590 #ifdef HPCGAP
591 Int IsInternallyMutableObj(Obj obj);
592 #endif
593
594 /****************************************************************************
595 **
596 *V SaveObjFuncs[ <type> ] . . . . . . . . . . . . functions to save objects
597 **
598 ** 'SaveObjFuncs' is the dispatch table that contains, for every type
599 ** of objects, a pointer to the saving function for objects of that type
600 ** These should not handle the file directly, but should work via the
601 ** functions 'SaveObjRef', 'SaveUInt<n>' (<n> = 1,2,4 or 8), and others
602 ** to be determined. Their role is to identify the C types of the various
603 ** parts of the bag, and perhaps to leave out some information that does
604 ** not need to be saved. By the time this function is called, the bag
605 ** size and type have already been saved.
606 ** No saving function may allocate any bag.
607 */
608
609 extern void (*SaveObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
610
611 void SaveObjError(Obj obj);
612
613
614 /****************************************************************************
615 **
616 *V LoadObjFuncs[ <type> ] . . . . . . . . . . . . functions to load objects
617 **
618 ** 'LoadObjFuncs' is the dispatch table that contains, for every type
619 ** of objects, a pointer to the loading function for objects of that type
620 ** These should not handle the file directly, but should work via the
621 ** functions 'LoadObjRef', 'LoadUInt<n>' (<n> = 1,2,4 or 8), and others
622 ** to be determined. Their role is to reinstall the information in the bag
623 ** and reconstruct anything that was left out. By the time this function is
624 ** called, the bag size and type have already been loaded and the bag argument
625 ** contains the bag in question.
626 ** No loading function may allocate any bag.
627 */
628
629 extern void (*LoadObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
630
631 void LoadObjError(Obj obj);
632
633 /****************************************************************************
634 **
635 *F IS_COPYABLE_OBJ( <obj> ) . . . . . . . . . . . . . is an object copyable
636 **
637 ** 'IS_COPYABLE_OBJ' returns 1 if the object <obj> is copyable (i.e., can be
638 ** copied into a mutable object), and 0 otherwise.
639 */
640 extern Int (*IsCopyableObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
IS_COPYABLE_OBJ(Obj obj)641 EXPORT_INLINE Int IS_COPYABLE_OBJ(Obj obj)
642 {
643 UInt tnum = TNUM_OBJ(obj);
644 return (IsCopyableObjFuncs[tnum])(obj);
645 }
646
647
648 /****************************************************************************
649 **
650 *V ShallowCopyObjFuncs[<type>] . . . . . . . . . . shallow copier functions
651 *F SHALLOW_COPY_OBJ( <obj> ) . . . . . . . make a shallow copy of an object
652 **
653 ** 'SHALLOW_COPY_OBJ' makes a shallow copy of the object <obj>.
654 */
655 extern Obj (*ShallowCopyObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
SHALLOW_COPY_OBJ(Obj obj)656 EXPORT_INLINE Obj SHALLOW_COPY_OBJ(Obj obj)
657 {
658 UInt tnum = TNUM_OBJ(obj);
659 return (ShallowCopyObjFuncs[tnum])(obj);
660 }
661
662
663 /****************************************************************************
664 **
665 *F CopyObj( <obj> ) . . . . . . . . . . make a structural copy of an object
666 **
667 ** 'CopyObj' returns a structural (deep) copy of the object <obj>, i.e., a
668 ** recursive copy that preserves the structure.
669 */
670 Obj CopyObj(Obj obj, Int mut);
671
672
673 /****************************************************************************
674 **
675 *F COPY_OBJ(<obj>) . . . . . . . . . . . make a structural copy of an object
676 **
677 ** 'COPY_OBJ' implements the first pass of 'CopyObj', i.e., it makes the
678 ** structural copy of <obj> and marks <obj> as already copied.
679 **
680 ** 'COPY_OBJ' must only be used from within CopyObjFuncs functions. To copy
681 ** an object from regular code, call 'CopyObj'.
682 */
683 #if !defined(USE_THREADSAFE_COPYING)
684 Obj COPY_OBJ(Obj obj, Int mut);
685 #endif
686
687 /****************************************************************************
688 **
689 *F PrepareCopy(<obj>,<copy>) . . . helper for use in CopyObjFuncs functions
690 **
691 */
692 #if !defined(USE_THREADSAFE_COPYING)
693 void PrepareCopy(Obj obj, Obj copy);
694 #endif
695
696
697 /****************************************************************************
698 **
699 *F CLEAN_OBJ(<obj>) . . . . . . . . . . . . . clean up object after copying
700 **
701 ** 'CLEAN_OBJ' implements the second pass of 'CopyObj', i.e., it removes the
702 ** mark from <obj>.
703 */
704 #if !defined(USE_THREADSAFE_COPYING)
705 void CLEAN_OBJ(Obj obj);
706 #endif
707
708
709 /****************************************************************************
710 **
711 *V CopyObjFuncs[<type>] . . . . . . . . . . . . table of copying functions
712 **
713 ** A package implementing a nonconstant object type <type> must provide such
714 ** functions and install them in 'CopyObjFuncs[<type>]' and
715 ** 'CleanObjFuncs[<type>]'.
716 **
717 ** The function called by 'COPY_OBJ' should first create a copy of <obj>,
718 ** somehow mark <obj> as having already been copied, leave a forwarding
719 ** pointer to the copy in <obj>, and then copy all subobjects with
720 ** 'COPY_OBJ' recursively. If called for an already marked object, it
721 ** should simply return the value of the forward pointer. It should *not*
722 ** clear the mark, this is the job of 'CLEAN_OBJ' later.
723 **
724 ** The function called by 'CLEAN_OBJ' should clear the mark left by the
725 ** corresponding 'COPY_OBJ' function, remove the forwarding pointer, and
726 ** then call 'CLEAN_OBJ' for all subobjects recursively. If called for an
727 ** already unmarked object, it should simply return.
728 */
729 #if !defined(USE_THREADSAFE_COPYING)
730 extern Obj (*CopyObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj, Int mut );
731 #endif
732
733
734 /****************************************************************************
735 **
736 *V CleanObjFuncs[<type>] . . . . . . . . . . . . table of cleaning functions
737 */
738 #if !defined(USE_THREADSAFE_COPYING)
739 extern void (*CleanObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
740 #endif
741
742
743 /****************************************************************************
744 **
745 *V MakeImmutableObjFuncs[<type>] . . . . . . . . . . . . table of functions
746 */
747 extern void (*MakeImmutableObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
748
749
750 /****************************************************************************
751 **
752 *F PrintObj( <obj> ) . . . . . . . . . . . . . . . . . . . . print an object
753 **
754 ** 'PrintObj' prints the object <obj>.
755 */
756 void PrintObj(Obj obj);
757
758 extern Obj PrintObjOper;
759
760 /****************************************************************************
761 **
762 **
763 */
764 UInt SetPrintObjState(UInt state); // returns the old state
765 void SetPrintObjIndex(Int index);
766
767
768 /****************************************************************************
769 **
770 *V PrintObjFuncs[<type>] . . . . . . . . printer for objects of type <type>
771 **
772 ** 'PrintObjFuncs' is the dispatch table that contains for every type of
773 ** objects a pointer to the printer for objects of this type. The printer
774 ** is the function '<func>(<obj>)' that should be called to print the object
775 ** <obj> of this type.
776 */
777 extern void (* PrintObjFuncs[LAST_REAL_TNUM+1]) ( Obj obj );
778
779
780 /****************************************************************************
781 **
782 *F ViewObj( <obj> ) . . . . . . . . . . . . . . . . . . . . view an object
783 **
784 ** 'ViewObj' views the object <obj>.
785 */
786 void ViewObj(Obj obj);
787
788
789 /****************************************************************************
790 **
791 *V PrintPathFuncs[<type>] . . . . . . printer for subobjects of type <type>
792 **
793 ** 'PrintPathFuncs' is the dispatch table that contains for every
794 ** appropriate type of objects a pointer to the path printer for objects of
795 ** that type. The path printer is the function '<func>(<obj>,<indx>)' that
796 ** should be called to print the selector that selects the <indx>-th
797 ** subobject of the object <obj> of this type.
798 **
799 ** These are also used for viewing
800 */
801 extern void (* PrintPathFuncs[LAST_REAL_TNUM+1]) (
802 Obj obj,
803 Int indx );
804
805
806 /****************************************************************************
807 **
808 *F IS_COMOBJ( <obj> ) . . . . . . . . . . . is an object a component object
809 */
IS_COMOBJ(Obj obj)810 EXPORT_INLINE Int IS_COMOBJ(Obj obj)
811 {
812 return TNUM_OBJ(obj) == T_COMOBJ;
813 }
814
815
816 /****************************************************************************
817 **
818 *F TYPE_COMOBJ( <obj> ) . . . . . . . . . . . . type of a component object
819 */
TYPE_COMOBJ(Obj obj)820 EXPORT_INLINE Obj TYPE_COMOBJ(Obj obj)
821 {
822 return CONST_ADDR_OBJ(obj)[0];
823 }
824
825
826 /****************************************************************************
827 **
828 *F SET_TYPE_COMOBJ( <obj>, <val> ) . . . set the type of a component object
829 */
SET_TYPE_COMOBJ(Obj obj,Obj val)830 EXPORT_INLINE void SET_TYPE_COMOBJ(Obj obj, Obj val)
831 {
832 ADDR_OBJ(obj)[0] = val;
833 }
834
835
836 /****************************************************************************
837 **
838 *F AssComObj( <obj>, <rnam>, <val> )
839 *F UnbComObj( <obj>, <rnam> )
840 *F ElmComObj( <obj>, <rnam> )
841 *F IsbComObj( <obj>, <rnam> )
842 */
843 void AssComObj(Obj obj, UInt rnam, Obj val);
844 void UnbComObj(Obj obj, UInt rnam);
845 Obj ElmComObj(Obj obj, UInt rnam);
846 Int IsbComObj(Obj obj, UInt rnam);
847
848
849 /****************************************************************************
850 **
851 *F IS_POSOBJ( <obj> ) . . . . . . . . . . is an object a positional object
852 */
IS_POSOBJ(Obj obj)853 EXPORT_INLINE Int IS_POSOBJ(Obj obj)
854 {
855 return TNUM_OBJ(obj) == T_POSOBJ;
856 }
857
858
859 /****************************************************************************
860 **
861 *F TYPE_POSOBJ( <obj> ) . . . . . . . . . . . . type of a positional object
862 */
TYPE_POSOBJ(Obj obj)863 EXPORT_INLINE Obj TYPE_POSOBJ(Obj obj)
864 {
865 return CONST_ADDR_OBJ(obj)[0];
866 }
867
868
869 /****************************************************************************
870 **
871 *F SET_TYPE_POSOBJ( <obj>, <val> ) . . . set the type of a positional object
872 */
SET_TYPE_POSOBJ(Obj obj,Obj val)873 EXPORT_INLINE void SET_TYPE_POSOBJ(Obj obj, Obj val)
874 {
875 ADDR_OBJ(obj)[0] = val;
876 }
877
878
879 /****************************************************************************
880 **
881 *F AssPosbj( <obj>, <rnam>, <val> )
882 *F UnbPosbj( <obj>, <rnam> )
883 *F ElmPosbj( <obj>, <rnam> )
884 *F IsbPosbj( <obj>, <rnam> )
885 */
886 void AssPosObj(Obj obj, Int idx, Obj val);
887 void UnbPosObj(Obj obj, Int idx);
888 Obj ElmPosObj(Obj obj, Int idx);
889 Int IsbPosObj(Obj obj, Int idx);
890
891
892 /****************************************************************************
893 **
894 *F IS_DATOBJ( <obj> ) . . . . . . . . . . . . . is an object a data object
895 */
IS_DATOBJ(Obj obj)896 EXPORT_INLINE Int IS_DATOBJ(Obj obj)
897 {
898 return TNUM_OBJ(obj) == T_DATOBJ;
899 }
900
901
902 /****************************************************************************
903 **
904 *F TYPE_DATOBJ( <obj> ) . . . . . . . . . . . . . . . type of a data object
905 */
TYPE_DATOBJ(Obj obj)906 EXPORT_INLINE Obj TYPE_DATOBJ(Obj obj)
907 {
908 return CONST_ADDR_OBJ(obj)[0];
909 }
910
911
912 /****************************************************************************
913 **
914 *F SetTypeDatobj( <obj>, <kind> ) . . . . . . set the type of a data object
915 **
916 ** 'SetTypeDatobj' sets the kind <kind> of the data object <obj>.
917 */
SET_TYPE_DATOBJ(Obj obj,Obj val)918 EXPORT_INLINE void SET_TYPE_DATOBJ(Obj obj, Obj val)
919 {
920 ADDR_OBJ(obj)[0] = val;
921 }
922
923 void SetTypeDatObj(Obj obj, Obj type);
924
925
926 /****************************************************************************
927 **
928 *F NewKernelBuffer( <size> ) . . . . . . . . . . return a new kernel buffer
929 **
930 ** Return a new T_DATOBJ of the specified <size>, with its type set to the
931 ** special value TYPE_KERNEL_OBJECT.
932 **
933 ** Note that <size> must include storage for the the first slot of the bag,
934 ** which points to the type object.
935 */
936 Obj NewKernelBuffer(UInt size);
937
938
939 /****************************************************************************
940 **
941 *F * * * * * * * * * * * * * initialize module * * * * * * * * * * * * * * *
942 */
943
944
945 /****************************************************************************
946 **
947 *F InitInfoObjects() . . . . . . . . . . . . . . . . table of init functions
948 */
949 StructInitInfo * InitInfoObjects ( void );
950
951
952 #endif // GAP_OBJECTS_H
953