mirror of
https://github.com/autc04/Retro68.git
synced 2024-12-01 11:52:47 +00:00
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;
|
|
}
|