]> gitweb.factorcode.org Git - factor.git/blob - vm/local_roots.hpp
Merge branch 'master' of git://factorcode.org/git/factor
[factor.git] / vm / local_roots.hpp
1 namespace factor
2 {
3
4 /* If a runtime function needs to call another function which potentially
5 allocates memory, it must wrap any local variable references to Factor
6 objects in gc_root instances */
7 extern std::vector<cell> gc_locals;
8
9 template <typename T>
10 struct gc_root : public tagged<T>
11 {
12         void push() { check_tagged_pointer(tagged<T>::value()); gc_locals.push_back((cell)this); }
13         
14         explicit gc_root(cell value_) : tagged<T>(value_) { push(); }
15         explicit gc_root(T *value_) : tagged<T>(value_) { push(); }
16
17         const gc_root<T>& operator=(const T *x) { tagged<T>::operator=(x); return *this; }
18         const gc_root<T>& operator=(const cell &x) { tagged<T>::operator=(x); return *this; }
19
20         ~gc_root() {
21 #ifdef FACTOR_DEBUG
22                 assert(gc_locals.back() == (cell)this);
23 #endif
24                 gc_locals.pop_back();
25         }
26 };
27
28 /* A similar hack for the bignum implementation */
29 extern std::vector<cell> gc_bignums;
30
31 struct gc_bignum
32 {
33         bignum **addr;
34
35         gc_bignum(bignum **addr_) : addr(addr_) {
36                 if(*addr_)
37                         check_data_pointer(*addr_);
38                 gc_bignums.push_back((cell)addr);
39         }
40
41         ~gc_bignum() {
42 #ifdef FACTOR_DEBUG
43                 assert(gc_bignums.back() == (cell)addr);
44 #endif
45                 gc_bignums.pop_back();
46         }
47 };
48
49 #define GC_BIGNUM(x) gc_bignum x##__gc_root(&x)
50
51 }