Created
June 11, 2015 21:09
-
-
Save fowlmouth/7719641ed8052777701d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## test that storing Objects in slots of components is gc safe | |
import cmodel, std_test, gctester | |
gcTest: | |
let my_comp = dynaComponent("my_comp", "child1", "child2") | |
let aggx = aggregate(my_comp) | |
let my1 = aggx.instantiate() | |
let my2 = aggx.instantiate() | |
exprIncsRef(my1): | |
discard my2.send("child1:", my1) | |
exprReplacesRef(my2, my1): | |
discard my2.send("child1:", my2) | |
exprDecsRef(my2): | |
discard my2.send("child1:", nil.Object) | |
assert getRefCount(my1) == 0 | |
assert getRefCount(my2) == 0 | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
discard """ | |
a generic gc test? | |
what operations are required | |
- an expression that saves a ref must increment its reference | |
- an expression that replaces a ref must decrement the ref it held previously | |
- a gc-safe type decrements held references upon destruction (manual or automatic) | |
""" | |
template gcTest* (body: untyped): stmt {. dirty, immediate } = | |
template exprIncsRef (rf, xpr: untyped): stmt = | |
{.line: instantiationInfo() }: | |
block: | |
let rc = getRefCount(rf) | |
block: xpr | |
GC_fullCollect() | |
do_assert( | |
not rf.isNil and getRefCount(rf) == rc+1, | |
"expression did not incref: "& astToStr(xpr) ) | |
template exprDecsRef (rf, xpr: untyped): stmt = | |
{.line: instantiationInfo() }: | |
block: | |
do_assert(not rf.isNil, "reference is not valid! "& $instantiationInfo()) | |
let old_rf = rf | |
let old_rc = getRefCount(rf) | |
block: xpr | |
GC_fullCollect() | |
do_assert( | |
getRefCount(old_rf) == old_rc-1, | |
"expression did not dec ref "& astToStr(xpr) | |
) | |
template exprReplacesRef (newRf, oldRf, xpr: untyped): stmt = | |
{.line: instantiationInfo() }: | |
exprIncsRef(newRf): | |
exprDecsRef(oldRf): | |
xpr | |
template exprDoesntRef (oldRf, xpr: untyped): stmt = | |
{.line: instantiationInfo() }: | |
let old_rc = getRefCount(oldRf) | |
xpr | |
GC_fullCollect() | |
do_assert getRefCount(oldRf) == old_rc, "expression did not keep ref "& astToStr(xpr) | |
try: | |
body | |
except: | |
echo("Unhandled exception: " & getCurrentExceptionMsg()) | |
echo getCurrentException().getStackTrace() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cmodel | |
GC_fullCollect() | |
template primitiveComponent* (ty:typedesc): (Component,AggregateType) = | |
(typeComponent(ty), aggregate(typeComponent(ty))) | |
template defPrimitiveComponent*(n,comp: untyped): stmt = | |
let (`cx n`*{.inject.}, `aggx n`*{.inject.}) = primitiveComponent(comp) | |
`cx n`.name = astToStr(n) | |
proc `obj n`* (some: `comp`): Object = | |
result = `aggx n`.instantiate | |
result.findDataM(comp) = some | |
proc asObject* (some: `comp`): Object{.inline.}= | |
`obj n`(some) | |
template setData* (ob:Object; dat:typed) = | |
ob.findDataM(type(dat)) = dat | |
proc sendAll* (ob:Object; msg:string; args:varargs[Object]): Object = | |
for r in ob.multicast(msg, args): | |
result = r |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment