August 22, 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:
> What do you think?

Well, one suggestion would be to simply version Object.factory so that programs that don't need it and don't want the bloat can define a version which versions it out. The it won't pull in all of the TypeInfos, and you won't get that bloat. It's not exactly an ideal solution, but it's easy enough to do that it might be worth it to get rid of that bloat for the folks who can't afford it.

I do agree though that we should try and find a better way to fix the problem so that the situation is improved for everyone.

- Jonathan M Davis
August 22, 2015
On Friday, 21 August 2015 at 21:37:34 UTC, Walter Bright wrote:
> On 8/21/2015 4:44 AM, Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm@gmx.net> wrote:
>> Just change Object.factory to require registration of the class.
>
> What mechanism do you propose for that?

E.g.:

    template factoryConstructors(Args...) {
        // using void* because I don't know whether it's possible
        // to have a function pointer to a constructor
        void*[string] factoryConstructors;
    }

    void registerFactoryConstructor(Class, Args...)()
    if(is(Class == class))
    {
        factoryConstructors!Args[Class.stringof] = ...;
    }

    Object factory(Args...)(string className, Args args) {
        auto constructor = factoryConstructors!Args[className];
        return ...;
    }

This even allows to call constructors with arguments. deadalnix's proposal is a nice way to automate this for an entire class hierarchy. Another possible mechanisms would be some UDA magic.
August 22, 2015
On Saturday, 22 August 2015 at 08:16:06 UTC, Marc Schütz wrote:
> Another possible mechanisms would be some UDA magic.

E.g.:

    class MyClass {
        @factorizable
        this() { }
        @factorizable
        this(string) { }
        this(int) { }
    }

    mixin registerFactoryConstructors; // for entire module
August 22, 2015
On Friday, 21 August 2015 at 13:47:49 UTC, Andrei Alexandrescu wrote:
> Thanks for this list. I think these need to be fixed (by replacing indirect-calls-based code with templates) regardless of where we go with TypeInfo. There's a fair amount of druntime code that suffers from being written before templates or in avoidance thereof. -- Andrei

Yes, it's a major pain and a source for many incorrect attributes.
August 22, 2015
Am Fri, 21 Aug 2015 11:46:21 +0000
schrieb "Kagamin" <spam@here.lot>:

> On Friday, 21 August 2015 at 11:03:09 UTC, Mike wrote:
> > * postblit - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR918 * destructor - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-1f51c84492753de4c1863d02e24318bbR1039
> 
> Looks like these are generated for fixed sized array of structs in a struct.
> 
> > * slicing - https://github.com/D-Programming-GDC/GDC/pull/100/files?diff=unified#diff-5960d486a42197785b9eee4ba95c6b95R11857
> 
> Can't even understand, what is this. Array op? But array ops are handled just above.

If you do
'array[] = n'
the compiler calls one of _d_arraysetctor,
_d_arraysetassign, _d_arrayassign, _d_arrayctor or _d_arraycopy.

http://wiki.dlang.org/Runtime_Hooks

The calls basically copy n to the array and call the postblit for every value in array[]. They also call 'TypeInfo.destroy' (destructor) on old values before overwriting. arraycopy doesn't use TypeInfo. The rest could be easily rewritten to be templated* or completely compiler generated.

* I'm not sure if we support manually accessing the postblit of a type.
  OTOH if these functions were templated the compiler would likely emit
  the correct postblit/destroy calls automatically.
August 22, 2015
Am Fri, 21 Aug 2015 15:16:01 +0200
schrieb Iain Buclaw via Digitalmars-d <digitalmars-d@puremagic.com>:

> 
> Other than that, the semantics of pragma(inline, true) should guarantee that the function is never *written* to object file.
> 

This really should be documented then. If we build a shared library with pragma(inline) functions not emitting the function prevents taking the address of that function in all client code. As this is a breaking change to 'normal' inline semantics it needs to be documented.

https://github.com/D-Programming-Language/dlang.org/pull/1073
August 22, 2015
On Friday, 21 August 2015 at 20:28:47 UTC, Walter Bright wrote:
>> Btw we use it for high-level testing framework - will be rather hard to move
>> that to compile-time approach
>
> It's good to hear of use cases for Object.factory.

If you want details it is special library for black box testing applications by spawning them as external processes and interacting with their shell/network API. To minimize boilerplate test scenarios are derived from special TestCase class and test runner finds all classes that derive from TestCase automatically.

Marking them all as export will be inconvenient but is possible - but I'd like to get something useful in return, like well-defined and working export for example.

> > until some reflection bugs gets fixed.
>
> Bugzilla issues? (You knew that was coming!)

https://issues.dlang.org/show_bug.cgi?id=11595 is the main offender. Currently the task 'find all symbols with a given trait in the whole program' can't be implemented at CT.
August 22, 2015
On Friday, 21 August 2015 at 05:06:47 UTC, Walter Bright wrote:
> The solution seems straightforward - only have Object.factory be able to instantiate classes marked as 'export'. This only makes sense anyway.

The export seems to be an arbitrary rule (and export is really broken currently).
Let's just use every class that is linked into the binary (e.g. weakly referencing them), then it'll naturally work with all linker functionalities.

This doesn't only affect Object.factory but also ModuleInfo.localClasses.
I'd suggest we first add a new internal array of weakly linked classes, turn localClasses into an opApply function or range so it automatically skips null classes (weakly undefined), then change Object.factory to only load weakly linked classes.

For an intermediate time we can keep the old array and print a deprecation warning in Object.factory when a class would no longer be available.
https://github.com/D-Programming-Language/dmd/pull/4638
August 22, 2015
On Friday, 21 August 2015 at 13:47:49 UTC, Andrei Alexandrescu wrote:

> I think these need to be fixed (by replacing indirect-calls-based code with templates) regardless of where we go with TypeInfo. There's a fair amount of druntime code that suffers from being written before templates or in avoidance thereof. -- Andrei

For whatever it's worth, below is a list of druntime functions that take TypeInfo as a parameter.  My immediate need is to make it possible for an -fno-rtti switch to be added to the compiler with as little compromise as possible.  In general, I'm not actually trying disable D features, even those that I don't actually need.  I only need to remove dead code.  If -fno-rtti is the best I can hope for, than I'll take it.

Perhaps templating some of these functions will make an -fno-rtti switch more viable. I'm judging from the comments in this thread that there may be additional benefits.

Would submitting pull requests towards this goal be a distraction from current priorities?   Should I wait until after DDMD is out?

Mike


\core\memory.d
143  extern (C) void gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc;
364  static void* malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow
390  static BlkInfo qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow
417  static void* calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow
457  static void* realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) pure nothrow
501  static size_t extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) pure nothrow
754  static void addRange( in void* p, size_t sz, const TypeInfo ti = null ) @nogc nothrow /* FIXME pure */

\object.d
1761 inout(void)[] _aaValues(inout void* p, in size_t keysize, in size_t valuesize, const TypeInfo tiValArray) pure nothrow;
1762 inout(void)[] _aaKeys(inout void* p, in size_t keysize, const TypeInfo tiKeyArray) pure nothrow;
1778 int _aaEqual(in TypeInfo tiRaw, in void* e1, in void* e2);
1779 hash_t _aaGetHash(in void* aa, in TypeInfo tiRaw) nothrow;
2794 extern (C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow;
2795 extern (C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void *arrptr) pure nothrow;
3231 private extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow;

\core\stdc\stdarg.d
60   void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
131  void va_arg()(ref va_list ap, TypeInfo ti, void* parmn)
345  void va_arg()(va_list apx, TypeInfo ti, void* parmn)

\gc\proxy.d
58   void function(void*, size_t, const TypeInfo ti) gc_addRange;
184  void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
191  BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
203  void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
210  void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null ) nothrow
217  size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null ) nothrow
282  void gc_addRange( void* p, size_t sz, const TypeInfo ti = null ) nothrow

\gcstub\gc.d
65   extern (C) void function(void*, size_t, const TypeInfo ti) gc_addRange;
184  extern (C) void* gc_malloc( size_t sz, uint ba = 0, const TypeInfo ti = null )
197  extern (C) BlkInfo gc_qalloc( size_t sz, uint ba = 0, const TypeInfo ti = null )
210  extern (C) void* gc_calloc( size_t sz, uint ba = 0, const TypeInfo ti = null )
223  extern (C) void* gc_realloc( void* p, size_t sz, uint ba = 0, const TypeInfo ti = null )
236  extern (C) size_t gc_extend( void* p, size_t mx, size_t sz, const TypeInfo ti = null )
293  extern (C) void gc_addRange( void* p, size_t sz, const TypeInfo ti = null )

\rt\arrayassign.d
27   extern (C) void[] _d_arrayassign(TypeInfo ti, void[] from, void[] to)
49   extern (C) void[] _d_arrayassign_l(TypeInfo ti, void[] src, void[] dst, void* ptmp)
141  extern (C) void[] _d_arrayassign_r(TypeInfo ti, void[] src, void[] dst, void* ptmp)
167  extern (C) void[] _d_arrayctor(TypeInfo ti, void[] from, void[] to)
205  extern (C) void* _d_arraysetassign(void* p, void* value, int count, TypeInfo ti)
236  extern (C) void* _d_arraysetctor(void* p, void* value, int count, TypeInfo ti)

\rt\aaA.d
438  extern (C) inout(void[]) _aaValues(inout AA aa, in size_t keysz, in size_t valsz, const TypeInfo tiValueArray) pure nothrow
461  extern (C) inout(void[]) _aaKeys(inout AA aa, in size_t keysz, const TypeInfo tiKeyArray) pure nothrow
567  extern (C) int _aaEqual(in TypeInfo tiRaw, in AA aa1, in AA aa2)
597  extern (C) hash_t _aaGetHash(in AA* aa, in TypeInfo tiRaw) nothrow

\rt\adi.d
24   extern (C) void[] _adSort(void[] a, TypeInfo ti);
365  extern (C) int _adEq(void[] a1, void[] a2, TypeInfo ti)
386  extern (C) int _adEq2(void[] a1, void[] a2, TypeInfo ti)
415  extern (C) int _adCmp(void[] a1, void[] a2, TypeInfo ti)
445  extern (C) int _adCmp2(void[] a1, void[] a2, TypeInfo ti)

\gc\gc.d
484  void *malloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow
516  private void *mallocNoSync(size_t size, uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow
546  void *calloc(size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow
578  void *realloc(void *p, size_t size, uint bits = 0, size_t *alloc_size = null, const TypeInfo ti = null) nothrow
603  private void *reallocNoSync(void *p, size_t size, ref uint bits, ref size_t alloc_size, const TypeInfo ti = null) nothrow
753  size_t extend(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow
766  private size_t extendNoSync(void* p, size_t minsize, size_t maxsize, const TypeInfo ti = null) nothrow
1178 void addRange(void *p, size_t sz, const TypeInfo ti = null) nothrow @nogc
1568 void addRange(void *pbot, void *ptop, const TypeInfo ti) nothrow @nogc
1826 void* bigAlloc(size_t size, ref size_t alloc_size, uint bits, const TypeInfo ti = null) nothrow

\rt\qsort.d
26   extern (C) void[] _adSort(void[] a, TypeInfo ti)
41   extern (C) void[] _adSort(void[] a, TypeInfo ti)
56   extern (C) void[] _adSort(void[] a, TypeInfo ti)
68   private TypeInfo tiglobal;
70   extern (C) void[] _adSort(void[] a, TypeInfo ti)

\rt\typeinfo\ti_Aint.d
19   extern (C) void[] _adSort(void[] a, TypeInfo ti);

\rt\tracegc.d
87   extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length);
88   extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length);
89   extern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims);
90   extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims);
109  extern (C) void[] _d_newarrayTTrace(string file, int line, string funcname, const TypeInfo ti, size_t length)
125  extern (C) void[] _d_newarrayiTTrace(string file, int line, string funcname, const TypeInfo ti, size_t length)
141  extern (C) void[] _d_newarraymTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t[] dims)
160  extern (C) void[] _d_newarraymiTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t[] dims)
179  extern (C) void* _d_newitemTTrace(string file, int line, string funcname, in TypeInfo ti)
194  extern (C) void* _d_newitemiTTrace(string file, int line, string funcname, in TypeInfo ti)
214  extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf)
274  extern (C) void _d_delstructTrace(string file, int line, string funcname, void** p, TypeInfo_Struct inf)
319  extern (C) void* _d_arrayliteralTX(const TypeInfo ti, size_t length);
322  extern (C) void* _d_arrayliteralTXTrace(string file, int line, string funcname, const TypeInfo ti, size_t length)
358  extern (C) byte[] _d_arraycatT(const TypeInfo ti, byte[] x, byte[] y);
359  extern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs);
361  extern (C) byte[] _d_arraycatTTrace(string file, int line, string funcname, const TypeInfo ti, byte[] x, byte[] y)
378  extern (C) void[] _d_arraycatnTXTrace(string file, int line, string funcname, const TypeInfo ti, byte[][] arrs)
397  extern (C) void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, byte[] y);
398  extern (C) byte[] _d_arrayappendcTX(const TypeInfo ti, ref byte[] px, size_t n);
402  extern (C) void[] _d_arrayappendTTrace(string file, int line, string funcname, const TypeInfo ti, ref byte[] x, byte[] y)
419  extern (C) byte[] _d_arrayappendcTXTrace(string file, int line, string funcname, const TypeInfo ti, ref byte[] px, size_t n)
480  extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p);
481  extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p);
483  extern (C) void[] _d_arraysetlengthTTrace(string file, int line, string funcname, const TypeInfo ti, size_t newlength, void[]* p)
500  extern (C) void[] _d_arraysetlengthiTTrace(string file, int line, string funcname, const TypeInfo ti, size_t newlength, void[]* p)

\rt\lifetime.d
180  extern (C) void _d_delstruct(void** p, TypeInfo_Struct inf)
215  size_t structTypeInfoSize(const TypeInfo ti) pure nothrow @nogc
269  bool __setArrayAllocLength(ref BlkInfo info, size_t newlength, bool isshared, const TypeInfo tinext, size_t oldlength = ~0) pure nothrow
374  size_t __arrayAllocLength(ref BlkInfo info, const TypeInfo tinext) pure nothrow
398  size_t __arrayPad(size_t size, const TypeInfo tinext) nothrow pure @trusted
407  BlkInfo __arrayAlloc(size_t arrsize, const TypeInfo ti, const TypeInfo tinext) nothrow pure
421  BlkInfo __arrayAlloc(size_t arrsize, ref BlkInfo info, const TypeInfo ti, const TypeInfo tinext)
631  extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) /+nothrow+/
670  package bool hasPostblit(in TypeInfo ti)
675  void __doPostblit(void *ptr, size_t len, const TypeInfo ti)
712  extern(C) size_t _d_arraysetcapacity(const TypeInfo ti, size_t newcapacity, void[]* p)
882  extern (C) void[] _d_newarrayU(const TypeInfo ti, size_t length) pure nothrow
941  extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length) pure nothrow
954  extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow
987  void[] _d_newarrayOpT(alias op)(const TypeInfo ti, size_t[] dims)
1028 extern (C) void[] _d_newarraymTX(const TypeInfo ti, size_t[] dims)
1044 extern (C) void[] _d_newarraymiTX(const TypeInfo ti, size_t[] dims)
1413 extern (C) void[] _d_arraysetlengthT(const TypeInfo ti, size_t newlength, void[]* p)
1597 extern (C) void[] _d_arraysetlengthiT(const TypeInfo ti, size_t newlength, void[]* p)
1794 extern (C) void[] _d_arrayappendT(const TypeInfo ti, ref byte[] x, byte[] y)
1894 byte[] _d_arrayappendcTX(const TypeInfo ti, ref byte[] px, size_t n)
2076 extern (C) byte[] _d_arraycatT(const TypeInfo ti, byte[] x, byte[] y)
2141 extern (C) void[] _d_arraycatnTX(const TypeInfo ti, byte[][] arrs)
2180 void* _d_arrayliteralTX(const TypeInfo ti, size_t length)




August 22, 2015
On 21 August 2015 at 13:35, Steven Schveighoffer via Digitalmars-d < digitalmars-d@puremagic.com> wrote:

> On 8/21/15 7:22 AM, Iain Buclaw via Digitalmars-d wrote:
>
>> Where removing RTTI disables D feature's in a compromising way, I'd start by questioning the why.
>>
>> Eg:  Why does array literals need RTTI?  Looking at _d_arrayliteralTX implementation, it only does the following with the given TypeInfo provided:
>>
>> - Get the array element size (this is known at compile time)
>> - Get the array element type flags (calculated during the codegen stage,
>> but otherwise known at compile time)
>> - Test if the TypeInfo is derived from TypeInfo_Shared (can be done at -
>> you guessed it - compile time by peeking through the baseClass linked
>> list for a given TypeInfo type we are passing).
>>
>> So we have this function that accepts a TypeInfo, but doesn't really *need* to at all.
>>
>> void* _d_arrayliteralTX(size_t length, size_t sizeelem, uint flags, bool
>> isshared);
>>
>> Just putting it out there....
>>
>
> I strongly suggest we *don't* go this route. This means that any changes to what is required for the runtime to properly construct an array requires a compiler change.
>
> A MUCH better solution:
>
> T[] _d_arrayliteral(T)(size_t length)
>
> Also, isn't the typeinfo now stored by the GC so it can call the dtor? Perhaps that is done in the filling of the array literal, but I would be surprised as this is a GC feature.
>
>
I only looked at 2.066.1, the runtime implementation did not pass the typeinfo to the GC.