Runtime reflection idea

Adam D. Ruppe destructionator at gmail.com
Sun Jun 2 08:10:09 PDT 2013


On Sunday, 2 June 2013 at 13:28:28 UTC, Rainer Schuetze wrote:
> and TypeInfo.rtInfo() would then return a pointer to RTInfoData 
> instead of void*. This doesn't make it modifiable from outside 
> object.di, but I have no idea how that could be possible to 
> begin with (without recompiling the runtime library).

I think I have something figured out:

use side:

// i'll use this as a UDA
struct InfoStruct {
         string info;
}

// and this as the template extension
struct MoreRtInfo {
         string amazing;
}

@CustomInfo!(InfoStruct("info struct data")) // UDA style, goes 
into an array
class RTTest {
        // template style, goes in a special member
         static template userRtInfo(This) {
                 static __gshared i = MoreRtInfo("amazingness");
                 enum userRtInfo = &i;
         }
}


Retrieve:

         auto info = typeid(RTTest).rtInfo();
         if(info is null)
                 throw new Exception("wtf");

         auto urtInfo = info.userRtInfo; // this is from the 
template..
         if(urtInfo is null)
                 write("urtInfo == null\n");
         else {
                // it comes out as a void*, so we have to cast it 
back.
                 auto urt = cast(immutable(MoreRtInfo)*) urtInfo;
                 write("cool ",urt.amazing,"\n");
         }

         // and this is fetching the CustomInfo UDA
         auto cd = info.getCustomInfo!InfoStruct;
         if(cd is null) // it returns a InfoStruct*, like AA's in 
operator
                 write("InfoStruct is null\n");
         else
                 write(cd.info, "\n");







And the implementation side in object.d:



         struct MoreTypeInfo {
                 // other stuff druntime is free to declare
                 hash_t hash;
                 string stringOf;

                  // holder for the template thing
                 immutable(void)* userRtInfo;

                  // holder for the UDA thing
                 immutable(CustomTypeInfoExtension)[] customInfo;

                  // helper for the UDA get
                 immutable(T)* getCustomInfo(T)() immutable {
                         auto hash = typeid(T); // typehash!T;
                         foreach(ci; customInfo) {
                                 if(ci.typeOfData == hash)
                                         return 
cast(immutable(T)*) ci.data();
                         }
                         return null;
                 }
         }


        // instantiates the T.userRtInfo, if possible
         template urtInfo(T) {
                 static if (__traits(compiles, { auto a = 
cast(immutable(void)*) T.userRtInfo!T; }))
                         enum urtInfo = cast(immutable(void)*) 
T.userRtInfo!T;
                 else
                         enum urtInfo = null;
         }


         template RTInfo(T) {
                 __gshared static immutable minfo = MoreTypeInfo(
                       // stuff druntime is free to add
                       typehash!T, T.stringof,

                        // the user defined template
                         urtInfo!T,

                        // getting the UDA stuff
                         getCustomInfoInternal!T);
                 enum RTInfo = &minfo;
         }

         // finally, helpers in getting the UDAs, I posted this 
before too

         struct CustomTypeInfoExtension {
                 TypeInfo typeOfData;
                 // ctfe complained when I tried to just do 
&static_data
                 // so instead this little function helper does it 
for us
                 void* function() data;
         }

         immutable(CustomTypeInfoExtension)[] 
getCustomInfoInternal(T)() {
                 if(__ctfe) {
                         //bool[hash_t] seen;
                         immutable(CustomTypeInfoExtension)[] ext;
                         foreach(attr; __traits(getAttributes, T))
                                 static if(is(typeof(attr) == 
CustomTypeInfoExtension)) {
                                         //auto hash = 
attr.typeOfData.rtInfo.hash;
                                         //if(hash in seen)
                                                 //assert(0, 
"repeated data");
                                         //seen[hash] = true;
                                         ext ~= cast(immutable) 
attr;
                                 }
                         return ext;
                 } else return null;
         }

        // this is the user uses: @CustomInfo!(something)
         template CustomInfo(alias T) {
                 __gshared static data = T;
                 void* getRaw() { return cast(void*) &data; }
                 enum CustomInfo = CustomTypeInfoExtension( 
typeid(typeof(data))/*typehash!(typeof(data))*/, &getRaw);
         }



> Unfortunately the compiler sometimes doesn't force the 
> generation of RTInfo, but sets the m_rtInfo to 0 or 1 depending 
> on whether the Type contains pointers or not. I always wanted 
> to figure out why that happens...

weird


More information about the Digitalmars-d mailing list