| 
									
										
										
										
											2009-11-02 19:11:12 -05:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template<typename Type> | 
					
						
							|  |  |  | struct data_root : public tagged<Type> { | 
					
						
							|  |  |  | 	factor_vm *parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	void push() | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2009-11-06 06:30:37 -05:00
										 |  |  | 		parent->data_roots.push_back(data_root_range(&this->value_,1)); | 
					
						
							| 
									
										
										
										
											2009-11-02 19:11:12 -05:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	explicit data_root(cell value_, factor_vm *parent_) | 
					
						
							|  |  |  | 		: tagged<Type>(value_), parent(parent_) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		push(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	explicit data_root(Type *value_, factor_vm *parent_) : | 
					
						
							|  |  |  | 		tagged<Type>(value_), parent(parent_) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		push(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	const data_root<Type>& operator=(const Type *x) { tagged<Type>::operator=(x); return *this; } | 
					
						
							|  |  |  | 	const data_root<Type>& operator=(const cell &x) { tagged<Type>::operator=(x); return *this; } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	~data_root() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		parent->data_roots.pop_back(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* A similar hack for the bignum implementation */ | 
					
						
							|  |  |  | struct gc_bignum { | 
					
						
							|  |  |  | 	bignum **addr; | 
					
						
							|  |  |  | 	factor_vm *parent; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	gc_bignum(bignum **addr_, factor_vm *parent_) : addr(addr_), parent(parent_) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if(*addr_) parent->check_data_pointer(*addr_); | 
					
						
							|  |  |  | 		parent->bignum_roots.push_back((cell)addr); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	~gc_bignum() | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | #ifdef FACTOR_DEBUG
 | 
					
						
							|  |  |  | 		assert(parent->bignum_roots.back() == (cell)addr); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 		parent->bignum_roots.pop_back(); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GC_BIGNUM(x) gc_bignum x##__data_root(&x,this)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } |