mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			D
		
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			D
		
	
	
	
| module lib;
 | |
| 
 | |
| // test EH
 | |
| void throwException()
 | |
| {
 | |
|     throw new Exception(null);
 | |
| }
 | |
| 
 | |
| Exception collectException(void delegate() dg)
 | |
| {
 | |
|     try
 | |
|         dg();
 | |
|     catch (Exception e)
 | |
|         return e;
 | |
|     return null;
 | |
| }
 | |
| 
 | |
| // test GC
 | |
| __gshared Object root;
 | |
| void alloc() { root = new Object(); }
 | |
| void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized
 | |
| void free() { root = null; }
 | |
| 
 | |
| Object tls_root;
 | |
| void tls_alloc() { tls_root = new Object(); }
 | |
| void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized
 | |
| void tls_free() { tls_root = null; }
 | |
| 
 | |
| void stack(alias func)()
 | |
| {
 | |
|     // allocate some extra stack space to not keep references to GC memory on the scanned stack
 | |
|     ubyte[1024] buf = void;
 | |
|     func();
 | |
| }
 | |
| 
 | |
| void testGC()
 | |
| {
 | |
|     import core.memory;
 | |
| 
 | |
|     stack!alloc();
 | |
|     stack!tls_alloc();
 | |
|     stack!access();
 | |
|     stack!tls_access();
 | |
|     GC.collect();
 | |
|     stack!tls_access();
 | |
|     stack!access();
 | |
|     stack!tls_free();
 | |
|     stack!free();
 | |
| }
 | |
| 
 | |
| // test Init
 | |
| import core.atomic : atomicOp;
 | |
| shared uint shared_static_ctor, shared_static_dtor, static_ctor, static_dtor;
 | |
| shared static this() { if (atomicOp!"+="(shared_static_ctor, 1) != 1) assert(0); }
 | |
| shared static ~this() { if (atomicOp!"+="(shared_static_dtor, 1) != 1) assert(0); }
 | |
| static this() { atomicOp!"+="(static_ctor, 1); }
 | |
| static ~this() { atomicOp!"+="(static_dtor, 1); }
 | |
| 
 | |
| extern(C) int runTests()
 | |
| {
 | |
|     try
 | |
|         runTestsImpl();
 | |
|     catch (Throwable)
 | |
|         return 0;
 | |
|     return 1;
 | |
| }
 | |
| 
 | |
| void runTestsImpl()
 | |
| {
 | |
|     import core.thread;
 | |
| 
 | |
|     bool passed;
 | |
|     try
 | |
|         throwException();
 | |
|     catch (Exception e)
 | |
|         passed = true;
 | |
|     assert(passed);
 | |
|     assert(collectException({throwException();}) !is null);
 | |
| 
 | |
|     testGC();
 | |
| 
 | |
|     assert(shared_static_ctor == 1);
 | |
|     assert(static_ctor == 1);
 | |
|     static void run()
 | |
|     {
 | |
|         assert(static_ctor == 2);
 | |
|         assert(shared_static_ctor == 1);
 | |
|         testGC();
 | |
|     }
 | |
|     auto thr = new Thread(&run);
 | |
|     thr.start();
 | |
|     thr.join();
 | |
|     assert(static_dtor == 1);
 | |
| 
 | |
|     passed = false;
 | |
|     foreach (m; ModuleInfo)
 | |
|         if (m.name == "lib") passed = true;
 | |
|     assert(passed);
 | |
| }
 | |
| 
 | |
| // Provide a way to initialize D from C programs that are D agnostic.
 | |
| import core.runtime : rt_init, rt_term;
 | |
| 
 | |
| extern(C) int lib_init()
 | |
| {
 | |
|     return rt_init();
 | |
| }
 | |
| 
 | |
| extern(C) int lib_term()
 | |
| {
 | |
|     return rt_term();
 | |
| }
 | |
| 
 | |
| shared size_t* _finalizeCounter;
 | |
| 
 | |
| class MyFinalizer
 | |
| {
 | |
|     ~this()
 | |
|     {
 | |
|         import core.atomic;
 | |
|         atomicOp!"+="(*_finalizeCounter, 1);
 | |
|     }
 | |
| }
 | |
| 
 | |
| class MyFinalizerBig : MyFinalizer
 | |
| {
 | |
|     ubyte[4096] _big = void;
 | |
| }
 | |
| 
 | |
| extern(C) void setFinalizeCounter(shared(size_t)* p)
 | |
| {
 | |
|     _finalizeCounter = p;
 | |
| }
 |