| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | namespace factor | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | /* If a runtime function needs to call another function which potentially
 | 
					
						
							| 
									
										
										
										
											2009-05-02 14:45:38 -04:00
										 |  |  | allocates memory, it must wrap any local variable references to Factor | 
					
						
							|  |  |  | objects in gc_root instances */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | extern segment *gc_locals_region; | 
					
						
							|  |  |  | extern cell gc_locals; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | DEFPUSHPOP(gc_local_,gc_locals) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | template <typename T> | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | struct gc_root : public tagged<T> | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	void push() { gc_local_push((cell)this); } | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	explicit gc_root(cell value_) : tagged<T>(value_) { push(); } | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 	explicit gc_root(T *value_) : tagged<T>(value_) { push(); } | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	const gc_root<T>& operator=(const T *x) { tagged<T>::operator=(x); return *this; } | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	const gc_root<T>& operator=(const cell &x) { tagged<T>::operator=(x); return *this; } | 
					
						
							| 
									
										
										
										
											2009-05-02 10:19:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 06:07:14 -04:00
										 |  |  | 	~gc_root() { | 
					
						
							|  |  |  | #ifdef FACTOR_DEBUG
 | 
					
						
							|  |  |  | 		cell old = gc_local_pop(); | 
					
						
							|  |  |  | 		assert(old == (cell)this); | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | 		gc_local_pop(); | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-03 06:48:03 -04:00
										 |  |  | /* A similar hack for the bignum implementation */ | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | extern segment *gc_bignums_region; | 
					
						
							|  |  |  | extern cell gc_bignums; | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-03 06:48:03 -04:00
										 |  |  | DEFPUSHPOP(gc_bignum_,gc_bignums) | 
					
						
							| 
									
										
										
										
											2009-05-02 05:04:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-03 06:48:03 -04:00
										 |  |  | struct gc_bignum | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	bignum **addr; | 
					
						
							| 
									
										
										
										
											2009-05-03 06:48:03 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	gc_bignum(bignum **addr_) : addr(addr_) { | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 		if(*addr_) | 
					
						
							|  |  |  | 			check_data_pointer(*addr_); | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 		gc_bignum_push((cell)addr); | 
					
						
							| 
									
										
										
										
											2009-05-04 02:00:30 -04:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-04 05:50:24 -04:00
										 |  |  | 	~gc_bignum() { assert((cell)addr == gc_bignum_pop()); } | 
					
						
							| 
									
										
										
										
											2009-05-03 06:48:03 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #define GC_BIGNUM(x) gc_bignum x##__gc_root(&x)
 | 
					
						
							| 
									
										
										
										
											2009-05-04 02:46:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | } |