Re: Variables should have the ability to be @nogc

2016-05-31 Thread Basile B. via Digitalmars-d

On Tuesday, 31 May 2016 at 23:46:59 UTC, Marco Leise wrote:

Am Tue, 31 May 2016 20:41:09 +
schrieb Basile B. :

The only thing is that I'm not sure about is the tri-state and 
the recursion. I cannot find a case where it would be 
justified.


The recursion is simply there to find pointers in nested 
structs and their GcScan annotations:


- the "auto" is like if there's no annotation.
- the "yes" seems useless because there is no case where the 
scanner should fail to detect members that are managed by the GC. 
It's for this case that things are a bit vague.


Otherwise only the "no" remains.

So far I'll go for this: https://dpaste.dzfl.pl/e3023ba6a7e2
with another annotation type name, for example 'AddGcRange' or 
'GcScan'.


Re: Variables should have the ability to be @nogc

2016-05-31 Thread Marco Leise via Digitalmars-d
Am Tue, 31 May 2016 20:41:09 +
schrieb Basile B. :

> The only thing is that I'm not sure about is the tri-state and 
> the recursion. I cannot find a case where it would be justified.

The recursion is simply there to find pointers in nested
structs and their GcScan annotations:

// A does not need scanning
struct A
{
B b;
}

struct B
{
@noScan void* p;
}

The tri-state may not be necessary, I don't remember my
rationale there. I do use GcScan.automatic as the default in
memory allocation for example with the option to force it to
yes or no. It gives you more control, just in case.

-- 
Marco



Re: Variables should have the ability to be @nogc

2016-05-31 Thread Basile B. via Digitalmars-d

On Tuesday, 31 May 2016 at 19:04:39 UTC, Marco Leise wrote:

Am Tue, 31 May 2016 15:53:44 +
schrieb Basile B. :

This solution seems smarter than using the existing '@nogc' 
attribute. Plus one also for the fact that nothing has to be 
done in DMD.


I just constrained myself to what can be done in user code from 
the start. :)


Did you encounter the issue with protected and private members 
?


For me when i've tested the template i've directly got some 
warnings. DMD interprets my 'getMember' calls as a deprecated 
abuse of bug 314 but in dmd 2.069 I would get true errors.


Actually it is in a large half-ported code base from C++ and I 
haven't ever had a running executable, nor did I test it with 
recent dmd versions. My idea was to mostly have @nogc code, but 
allow it for a transition time or places where GC use does not 
have an impact. Here is the code, free to use for all purposes.


Thx for sharing the template. When using '.tupleof' instead of 
the traits 'allMember'/'getMember' there's no issue with the 
visibility, which is awesome. It means that the template can be 
proposed very quickly in phobos.


The only thing is that I'm not sure about is the tri-state and 
the recursion. I cannot find a case where it would be justified.





Re: Variables should have the ability to be @nogc

2016-05-31 Thread Marco Leise via Digitalmars-d
Am Tue, 31 May 2016 15:53:44 +
schrieb Basile B. :

> This solution seems smarter than using the existing '@nogc' 
> attribute. Plus one also for the fact that nothing has to be done 
> in DMD.

I just constrained myself to what can be done in user code
from the start. :)

> Did you encounter the issue with protected and private members ?
> 
> For me when i've tested the template i've directly got some 
> warnings. DMD interprets my 'getMember' calls as a deprecated 
> abuse of bug 314 but in dmd 2.069 I would get true errors.

Actually it is in a large half-ported code base from C++ and I
haven't ever had a running executable, nor did I test it with
recent dmd versions. My idea was to mostly have @nogc code,
but allow it for a transition time or places where GC use
does not have an impact. Here is the code, free to use for
all purposes.


enum GcScan { no, yes, automatic }
enum noScan = GcScan.no;

template gcScanOf(T)
{
import std.typetuple;

static if (is(T == struct) || is(T == union))
{
enum isGcScan(alias uda) = is(typeof(uda) == GcScan);

GcScan findGcScan(List...)()
{
auto result = GcScan.automatic;
foreach (attr; List) if (is(typeof(attr) == GcScan))
result = attr;
return result;
}

enum gcScanOf()
{
auto result = GcScan.no;
foreach (i; Iota!(T.tupleof.length))
{
enum memberGcScan = 
findMatchingUda!(T.tupleof[i], isGcScan, true);
static if (memberGcScan.length == 0)
enum eval = 
gcScanOf!(typeof(T.tupleof[i]));
else
enum eval = evalGcScan!(memberGcScan, 
typeof(T.tupleof[i]));

static if (eval)
{
result = eval;
break;
}
}
return result;
}
}
else
{
static if (isStaticArray!T && is(T : E[N], E, size_t N))
enum gcScanOf = is(E == void) ? GcScan.yes : gcScanOf!E;
else
enum gcScanOf = hasIndirections!T ? GcScan.yes : 
GcScan.no;
}
}

enum evalGcScan(GcScan gc, T) = (gc == GcScan.automatic) ? gcScanOf!T : gc;

template findMatchingUda(alias symbol, alias func, bool optional = false, bool 
multiple = false)
{
import std.typetuple;

enum symbolName = __traits(identifier, symbol);
enum funcName   = __traits(identifier, func);

template Filter(List...)
{
static if (List.length == 0)
alias Filter = TypeTuple!();
else static if (__traits(compiles, func!(List[0])) && 
func!(List[0]))
alias Filter = TypeTuple!(List[0], Filter!(List[1 .. 
$]));
else
alias Filter = Filter!(List[1 .. $]);
}

alias filtered = Filter!(__traits(getAttributes, symbol));
static assert(filtered.length <= 1 || multiple,
  symbolName ~ " may only have one UDA matching " ~ 
funcName ~ ".");
static assert(filtered.length >= 1 || optional,
  symbolName ~ " requires a UDA matching " ~ funcName ~ 
".");

static if (multiple || optional)
alias findMatchingUda = filtered;
else static if (filtered.length == 1)
alias findMatchingUda = filtered[0];
}

-- 
Marco



Re: Variables should have the ability to be @nogc

2016-05-31 Thread Basile B. via Digitalmars-d

On Tuesday, 31 May 2016 at 14:47:12 UTC, Marco Leise wrote:
I "solved" it with a UDA called GcScan in my code. It can be 
attached to any field or type and is a tri-state. In the 
undecided case (GcScan.auto) it recursively scans for potential 
GC pointers, excluding those marked GcScan.no. In the decided 
case (GcScan.yes/no) it simply assumes the user knows better 
and short-circuits the recursion.


[...]


This solution seems smarter than using the existing '@nogc' 
attribute. Plus one also for the fact that nothing has to be done 
in DMD.


Did you encounter the issue with protected and private members ?

For me when i've tested the template i've directly got some 
warnings. DMD interprets my 'getMember' calls as a deprecated 
abuse of bug 314 but in dmd 2.069 I would get true errors.


Re: Variables should have the ability to be @nogc

2016-05-31 Thread Marco Leise via Digitalmars-d
I "solved" it with a UDA called GcScan in my code. It can be
attached to any field or type and is a tri-state. In the
undecided case (GcScan.auto) it recursively scans for potential
GC pointers, excluding those marked GcScan.no. In the decided
case (GcScan.yes/no) it simply assumes the user knows better
and short-circuits the recursion.

If I use a third party struct that contains pointers and does
not use my GcScan UDA, but is known not to point to GC memory,
I'd tag the outer level with @GcScan.no.

Memory allocation via malloc is also wrapped in a function (a
typed allocator) that takes GcScan as a hint, so it may or may
not add the freshly allocated memory as a GC range. Again,
GcScan.auto would trigger auto-detection from the type.

-- 
Marco



Re: Variables should have the ability to be @nogc

2016-05-31 Thread Basile B. via Digitalmars-d

On Tuesday, 31 May 2016 at 13:33:03 UTC, Basile B. wrote:

[...]
A solution would be, in 'make()', to statically determine if 
the aggregate contains arrays, pointers or classes. This is 
very simple, as seen for example in EMSI container library with 
the 'shouldAddGCRange' template. [...]


Please also note well that this template will certainly be 
affected by the fact the trait 'getMember' has a serious issue 
related to the target visibility, as reported here:


https://issues.dlang.org/show_bug.cgi?id=15371