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; }