Clean up functors so that the generated code looks sane with 'see'
[factor/jcg.git] / vm / local_roots.h
blobe852f9e54d8d525ddb2b43ad00c47c7646b2e60d
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 ...
12 foo(some_local);
14 ...
16 UNREGISTER_ROOT(some_local); */
17 F_SEGMENT *gc_locals_region;
18 CELL gc_locals;
20 DEFPUSHPOP(gc_local_,gc_locals)
22 #define REGISTER_ROOT(obj) gc_local_push((CELL)&obj)
23 #define UNREGISTER_ROOT(obj) \
24 { \
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;
32 CELL extra_roots;
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));
50 return true;
54 return false;
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()))