1 module lib; 2 3 // test EH 4 void throwException() 5 { 6 throw new Exception(null); 7 } 8 9 Exception 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; 20 void alloc() { root = new Object(); } 21 void access() { assert(root.toString() !is null); } // vtbl call will fail if finalized 22 void free() { root = null; } 23 24 Object tls_root; 25 void tls_alloc() { tls_root = new Object(); } 26 void tls_access() { assert(tls_root.toString() !is null); } // vtbl call will fail if finalized 27 void tls_free() { tls_root = null; } 28 29 void 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 36 void 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 52 import core.atomic : atomicOp; 53 shared uint shared_static_ctor, shared_static_dtor, static_ctor, static_dtor; 54 shared static this() { if (atomicOp!"+="(shared_static_ctor, 1) != 1) assert(0); } 55 shared static ~this() { if (atomicOp!"+="(shared_static_dtor, 1) != 1) assert(0); } 56 static this() { atomicOp!"+="(static_ctor, 1); } 57 static ~this() { atomicOp!"+="(static_dtor, 1); } 58 59 extern(C) int runTests() 60 { 61 try 62 runTestsImpl(); 63 catch (Throwable) 64 return 0; 65 return 1; 66 } 67 68 void 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. 102 import core.runtime : rt_init, rt_term; 103 104 extern(C) int lib_init() 105 { 106 return rt_init(); 107 } 108 109 extern(C) int lib_term() 110 { 111 return rt_term(); 112 } 113 114 shared size_t* _finalizeCounter; 115 116 class MyFinalizer 117 { 118 ~this() 119 { 120 import core.atomic; 121 atomicOp!"+="(*_finalizeCounter, 1); 122 } 123 } 124 125 class MyFinalizerBig : MyFinalizer 126 { 127 ubyte[4096] _big = void; 128 } 129 130 extern(C) void setFinalizeCounter(shared(size_t)* p) 131 { 132 _finalizeCounter = p; 133 } 134