1module lib; 2 3// test EH 4void throwException() 5{ 6 throw new Exception(null); 7} 8 9Exception collectException(void delegate() dg) 10{ 11 try 12 dg(); 13 catch (Exception e) 14 return e; 15 return null; 16} 17 18// test GC 19__gshared Object root; 20void alloc() { root = new Object(); } 21void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized 22void free() { root = null; } 23 24Object tls_root; 25void tls_alloc() { tls_root = new Object(); } 26void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized 27void tls_free() { tls_root = null; } 28 29void stack(alias func)() 30{ 31 // allocate some extra stack space to not keep references to GC memory on the scanned stack 32 ubyte[1024] buf = void; 33 func(); 34} 35 36void testGC() 37{ 38 import core.memory; 39 40 stack!alloc(); 41 stack!tls_alloc(); 42 stack!access(); 43 stack!tls_access(); 44 GC.collect(); 45 stack!tls_access(); 46 stack!access(); 47 stack!tls_free(); 48 stack!free(); 49} 50 51// test Init 52import core.atomic : atomicOp; 53shared uint shared_static_ctor, shared_static_dtor, static_ctor, static_dtor; 54shared static this() { if (atomicOp!"+="(shared_static_ctor, 1) != 1) assert(0); } 55shared static ~this() { if (atomicOp!"+="(shared_static_dtor, 1) != 1) assert(0); } 56static this() { atomicOp!"+="(static_ctor, 1); } 57static ~this() { atomicOp!"+="(static_dtor, 1); } 58 59extern(C) int runTests() 60{ 61 try 62 runTestsImpl(); 63 catch (Throwable) 64 return 0; 65 return 1; 66} 67 68void runTestsImpl() 69{ 70 import core.thread; 71 72 bool passed; 73 try 74 throwException(); 75 catch (Exception e) 76 passed = true; 77 assert(passed); 78 assert(collectException({throwException();}) !is null); 79 80 testGC(); 81 82 assert(shared_static_ctor == 1); 83 assert(static_ctor == 1); 84 static void run() 85 { 86 assert(static_ctor == 2); 87 assert(shared_static_ctor == 1); 88 testGC(); 89 } 90 auto thr = new Thread(&run); 91 thr.start(); 92 thr.join(); 93 assert(static_dtor == 1); 94 95 passed = false; 96 foreach (m; ModuleInfo) 97 if (m.name == "lib") passed = true; 98 assert(passed); 99} 100 101// Provide a way to initialize D from C programs that are D agnostic. 102import core.runtime : rt_init, rt_term; 103 104extern(C) int lib_init() 105{ 106 return rt_init(); 107} 108 109extern(C) int lib_term() 110{ 111 return rt_term(); 112} 113 114shared size_t* _finalizeCounter; 115 116class MyFinalizer 117{ 118 ~this() 119 { 120 import core.atomic; 121 atomicOp!"+="(*_finalizeCounter, 1); 122 } 123} 124 125class MyFinalizerBig : MyFinalizer 126{ 127 ubyte[4096] _big = void; 128} 129 130extern(C) void setFinalizeCounter(shared(size_t)* p) 131{ 132 _finalizeCounter = p; 133} 134