-
-
Notifications
You must be signed in to change notification settings - Fork 422
implement dup and idup library functions #760
Conversation
MartinNowak
commented
Apr 5, 2014
- uses inferrence for pure and nothrow
- allocates uninitialized memory using _d_newarrayU
| return 1; | ||
| } | ||
|
|
||
| int dg2() pure nothrow @safe //Fallback to typeid |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this "Fallback to typeid" comment is still relevant?
|
Awesome pull. I like it a lot. The only thing I regret (if I understood correctly), is that the inference happens thanks to CTFE. However, the actual implementation uses tid's run-time postblit, which is "pre-preemptively" marked as safe, pure nothrow. What worries me is that if the postblit does throw, what will happen, given the exception comes from a the non-throwing But this is a generic problem of typeinfo, not this specific implementation. |
|
I think it needs a little more tweaking, the inferrence should come from casting the postblit delegate in _getPostblit, but using @trusted breaks it. |
| { | ||
| // @@BUG 12523@@ wrong foreach argument type with ref and inout | ||
| version (none) if (__ctfe) | ||
| { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the meantime I've submitted a pull to fix this issue dlang/dmd#3424.
|
Lets fix dlang/dmd#3424 first, then we can probably achieve strong purity using inout. _Unconst!T[] dup(T)(T[] a) @trusted
if (is(typeof(() @safe { T a = T.init, b = a; })))
{}
_Unconst!T[] dup(T)(T[] a) @system
if (!is(typeof(() @safe { T a = T.init, b = a; })) &&
is(typeof(() @system { T a = T.init, b = a; })))
{} |
The overload idea seems like nice idea. I like it. But I'd really hate exposing a user to such an overload. It should be implementation detail, rather than public interface. How about: _Unconst!T[] dup(T)(T[] a)
{
static if (is(typeof(() @safe { T a = T.init, b = a; })))
return _dupTrusted(a);
else
return _dup(a);
}
_Unconst!T[] _dupTrusted(T)(T[] a) @trusted
{
return _dup(a);
}Well, it's still basically just a "nested trusted" that was un-nested, but there's only one now. Also, I think the code can be made shorter with But whatever gets the job done is fine by me. |
|
Good ideas, will try them tomorrow. |
|
Just hit another compiler bug Issue 12528. Also it's currently not possible to cast away const/immutable/inout in CTFE. |
|
I haven't reviewed the code in I am particularly thrilled see that the code was consolidated into an Let's have someone else review this too, and get it shipped! |
It's a necessity more than a feature, I'd still want to keep the amount of compile time reflection on druntime low because it might easily slow down compilation or increase binary sizes. |
| { | ||
| if(*length == cast(ubyte)oldlength) | ||
| *length = cast(ubyte)newlength; | ||
| else | ||
| return false; | ||
| } | ||
| catch (Throwable t) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh? Why would synchronized ever throw?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the lock/unlock functions of the Monitor interface aren't nothrow. IMO they should be, but it could break code. Maybe we can find a way to deprecate the missing nothrow.
|
Note that the following code should be successful with this PR: I understand that the compiler changes will still be needed to call the library function rather than adDup(), but this can be tested by temporarily naming things as Dup rather than dup. |
Thanks for the additional test cases, using |
|
@MartinNowak I'd like to get this one merged ASAP, so I can excise the corresponding ugly code out of the compiler. I also think a PR to change std.traits to use core.internal.traits would be great, to avoid code duplication. |
I'm fine with that. We can do it as soon as this is merged. |
| debug(PRINTF) printf(" p = %p\n", info.base); | ||
| // update the length of the array | ||
| auto arrstart = __arrayStart(info); | ||
| memset(arrstart, 0, size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are you doing a memset in an uninitialized allocation? It's duplicate work from what goes on in _d_newarrayiT. Did you just forget to remove it?
If anything, if BlkAttr.NO_SCAN is not set, then I'd expect a memset of memset(arrstart+size+pad, 0, info. size-size-pad).
Reading though rt.lifetime, this seems like something we never used to do anyways. Does the GC "know" it doesn't have to scan that data?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, that's a copy paste mistake.
|
Could you also add some unittest, that the result of a dup has capacity? EG: auto a = [1, 2, 3];
auto b = a.dup();
assert(b.capacity >= 3)Speaking of which, Phobos would love having access to an un-initialized allocation function, that has appendable info: https://issues.dlang.org/show_bug.cgi?id=12444 . But that's beyond the scope of this pull. |
- rewrite _d_newarrayT and _d_newarrayiT in terms of _d_newarrayU - mark all _d_newarray functions as pure nothrow - optimize initialization in _d_newarrayiT
- can infer @safe, pure and nothrow - strongly pure dup if element type implicitly convertible to mutable - allocates uninitialized memory using _d_newarrayU
|
Updated to hopefully address all the remaining issues. |
|
I'm a bit disappointed that the initial idea turned into 90 lines of convoluted template code. |
|
Thank you. Well done! |
implement dup and idup library functions
Indeed. The final result is somewhat "convoluted", but it works, and there's no duplicate code. May I bring to attention this issue: https://issues.dlang.org/show_bug.cgi?id=12512 |
|
This introduced regression https://issues.dlang.org/show_bug.cgi?id=12580 |
|
Hey... I was trying to duplicate the "static postblit cast" thingy in a phobos, and I don't think it's working at all. I think the only reason this is working is because of the ctfe appends. If I remove it, then the attribute tests start failing. I don't think the whole struct T
{
this(this) @system
{}
}
void main()
{
alias PostBlitT = typeof(function(void*){T a = T.init, b = a;});
pragma(msg, PostBlitT.stringof);
}gives me: But |
|
How does that even compile without |
|
Note that there seems to be a difference when using struct T
{
this(this) @system
{}
}
void main()
{
alias PostBlitTypeof = typeof(function(void*){T a = T.init, b = a;});
auto PostBlit = function(void*){T a = T.init, b = a;};
pragma(msg, __traits(getFunctionAttributes, PostBlitTypeof));
pragma(msg, __traits(getFunctionAttributes, typeof(PostBlit)));
pragma(msg, __traits(getFunctionAttributes, PostBlit));
}It's quite strange. But essentially, |
Note the comma, basically, we are defining b. EG: int a = 5, b = a; |
|
For a second there I thought it was another usage of the comma operator (well it is, but not the other evil comma operator :P). |
|
So you're saying we need to use this workaround. enum PostBlit = function(void*){T a = T.init, b = a;};
alias PostBlitT = typeof(PostBlit);Issue 12704 – typeof function literal incorrectly infers attributes |
|
Question: Can phobos access package functions in core? I need this for phobos, so I want to know the "cleanest" way? It would only be "temporary", since the idea would be for phobos to one day have a function that statically postblits without any run-time overhead, but still, I think there's enough duplication already. |
By that I meant "a function that statically knows how to postblit, without runtime introspection". |
Nope, |
|
Also, Phobos should be "just another library", and not get any special access to the druntime internals. |