From cae60abd7a4b9b1d541fb5133c78db263f0ca4ed Mon Sep 17 00:00:00 2001 From: Steven Schveighoffer Date: Thu, 24 Feb 2011 22:27:47 -0500 Subject: [PATCH] Updated clear(Object) to directly call rt_finalize, which does all the right things. This prevents dtors from running twice, and does not re-run the default ctor. --- import/object.di | 27 ++++++--------------------- src/object_.d | 25 ++++--------------------- 2 files changed, 10 insertions(+), 42 deletions(-) diff --git a/import/object.di b/import/object.di index 069e2acb88..30b858a2ad 100644 --- a/import/object.di +++ b/import/object.di @@ -12,6 +12,11 @@ */ module object; +private +{ + extern(C) void rt_finalize(void *ptr, bool det=true); +} + alias typeof(int.sizeof) size_t; alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t; alias ptrdiff_t sizediff_t; @@ -431,27 +436,7 @@ unittest void clear(T)(T obj) if (is(T == class)) { - 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); + rt_finalize(cast(void*)obj); } void clear(T)(ref T obj) if (is(T == struct)) diff --git a/src/object_.d b/src/object_.d index 2c408274be..0ee6738347 100644 --- a/src/object_.d +++ b/src/object_.d @@ -33,6 +33,7 @@ private extern (C) Object _d_newclass(TypeInfo_Class ci); extern (C) void _d_arrayshrinkfit(TypeInfo ti, void[] arr); extern (C) size_t _d_arraysetcapacity(TypeInfo ti, size_t newcapacity, void *arrptr); + extern (C) void rt_finalize(void *data, bool det=true); } // NOTE: For some reason, this declaration method doesn't work @@ -2540,27 +2541,7 @@ unittest void clear(T)(T obj) if (is(T == class)) { - 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); + rt_finalize(cast(void*)obj); } version(unittest) unittest @@ -2589,6 +2570,8 @@ version(unittest) unittest assert(destroyed); assert(a.s == "B"); } + // this test is invalid now that the default ctor is not run after clearing + version(none) { class C {