destructor order
Steven Schveighoffer
schveiguy at yahoo.com
Wed Jan 26 10:18:58 PST 2011
On Wed, 26 Jan 2011 12:26:22 -0500, Andrei Alexandrescu
<SeeWebsiteForEmail at erdani.org> wrote:
> On 1/26/11 10:17 AM, Steven Schveighoffer wrote:
>> On Wed, 26 Jan 2011 11:09:45 -0500, Andrej Mitrovic
>> <andrej.mitrovich at gmail.com> wrote:
>>
>>> I think I glanced over a recent svn commit that fixed this, though I'm
>>> not sure.
>>
>> No, it hasn't been fixed.
>>
>> The fix is *really* simple, just have clear call rt_finalize (as Sean
>> pointed out on the mailing list)
>>
>> -Steve
>
> Steve, if you could point out what I need to do I'll be glad to do it
> right now. Better yet, feel free to try your hand at a git commit. It's
> fun!
*sweats nervously* I don't know, I'd like to read about how git works
before doing a commit. I don't really understand it at all, I had the
same problem with subversion when I started using it.
The fix is really easy, just change clear to this:
void clear(T)(T obj) if (is(T == class))
{
rt_finalize(cast(void*)obj);
}
Here is the body of the current clear:
if (!obj) return;
auto ci = obj.classinfo;
auto defaultCtor =
cast(void function(Object)) ci.defaultConstructor;
version(none) // enforce isn't available in druntime
_enforce(defaultCtor || (ci.flags & 8) == 0);
immutable size = ci.init.length;
auto ci2 = ci;
do
{
auto dtor = cast(void function(Object))ci2.destructor;
if (dtor)
dtor(obj);
ci2 = ci2.base;
} while (ci2)
auto buf = (cast(void*) obj)[0 .. size];
buf[] = ci.init;
if (defaultCtor)
defaultCtor(obj);
And the body of rt_finalize
if (p) // not necessary if called from gc
{
ClassInfo** pc = cast(ClassInfo**)p;
if (*pc)
{
ClassInfo c = **pc;
byte[] w = c.init;
try
{
if (det || collectHandler is null ||
collectHandler(cast(Object)p))
{
do
{
if (c.destructor)
{
fp_t fp = cast(fp_t)c.destructor;
(*fp)(cast(Object)p); // call destructor
}
c = c.base;
} while (c);
}
if ((cast(void**)p)[1]) // if monitor is not null
_d_monitordelete(cast(Object)p, det);
(cast(byte*) p)[0 .. w.length] = w[];
}
catch (Throwable e)
{
onFinalizeError(**pc, e);
}
finally
{
*pc = null; // zero vptr
}
}
}
Note the eerie similarities :)
-Steve
More information about the Digitalmars-d
mailing list