1 /* If a runtime function needs to call another function which potentially
2 allocates memory, it must store any local variable references to Factor
3 objects on the root stack */
5 /* GC locals: stores addresses of pointers to objects. The GC updates these
6 pointers, so you can do
8 REGISTER_ROOT(some_local);
10 ... allocate memory ...
16 UNREGISTER_ROOT(some_local); */
17 F_SEGMENT
*gc_locals_region
;
20 DEFPUSHPOP(gc_local_
,gc_locals
)
22 #define REGISTER_ROOT(obj) gc_local_push((CELL)&obj)
23 #define UNREGISTER_ROOT(obj) \
25 if(gc_local_pop() != (CELL)&obj) \
26 critical_error("Mismatched REGISTER_ROOT/UNREGISTER_ROOT",0); \
29 /* Extra roots: stores pointers to objects in the heap. Requires extra work
30 (you have to unregister before accessing the object) but more flexible. */
31 F_SEGMENT
*extra_roots_region
;
34 DEFPUSHPOP(root_
,extra_roots
)
36 #define REGISTER_UNTAGGED(obj) root_push(obj ? tag_object(obj) : 0)
37 #define UNREGISTER_UNTAGGED(obj) obj = untag_object(root_pop())
39 /* We ignore strings which point outside the data heap, but we might be given
40 a char* which points inside the data heap, in which case it is a root, for
41 example if we call unbox_char_string() the result is placed in a byte array */
42 INLINE
bool root_push_alien(const void *ptr
)
44 if(in_data_heap_p((CELL
)ptr
))
46 F_BYTE_ARRAY
*objptr
= ((F_BYTE_ARRAY
*)ptr
) - 1;
47 if(objptr
->header
== tag_header(BYTE_ARRAY_TYPE
))
49 root_push(tag_object(objptr
));
57 #define REGISTER_C_STRING(obj) \
58 bool obj##_root = root_push_alien(obj)
59 #define UNREGISTER_C_STRING(obj) \
60 if(obj##_root) obj = alien_offset(root_pop())
62 #define REGISTER_BIGNUM(obj) if(obj) root_push(tag_bignum(obj))
63 #define UNREGISTER_BIGNUM(obj) if(obj) obj = (untag_object(root_pop()))