00001
00002
00003
00004 #ifndef DOTYPE_H
00005 #define DOTYPE_H
00006
00007 #include <stddef.h>
00008
00009
00010 class VObj;
00011 class DynI;
00012 class DynObj;
00013 class DoModuleC;
00014
00015 #include "utils/StructHeader.h"
00016
00017
00026 enum doCastAlgo {
00029 doCastLocal = 1,
00032 doCastCross = 2,
00037 doCastFull = 3,
00038 };
00039
00040
00041 typedef void* (*CreateVObjFn)(int *pvts);
00042
00043 typedef void (*DestroyVObjFn)(void *pv);
00044
00045 class DynObjTypeLinks;
00046 class DoModuleNode;
00047 class DoCompoundNode;
00048 struct DoTypeItem;
00049 struct DynObjType;
00050
00051
00052 struct DoBaseNode {
00053 enum { IsUnresolved=1, IsDynObjType=2, IsSideBaseDecl=4, IsAllocated=8 };
00054
00055 DoBaseNode( const DynObjType *base, short offset, int flags );
00056 DoBaseNode( const char *base_type, int flags );
00057 ~DoBaseNode(){ Release(); }
00058
00059 void Release();
00060 bool Unresolved() const { return _flags&IsUnresolved; }
00061 void ClearUnresolved(){ _flags&=~IsUnresolved; }
00062
00063 union { DynObjType* _base;
00064 const char* _base_type; };
00065 short _offset;
00066 short _flags;
00067 DoBaseNode* _nxt;
00068 };
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00088 struct DynObjType{
00089 public:
00090 DynObjType( const char *type, int type_id, int flags, int size, const void *_this=NULL, const void *_base_ptr=NULL, const char *header=NULL );
00091
00092 DynObjType( const char *type, const char *base, int type_id, int flags, int size, const void *_this=NULL, const void *_base_ptr=NULL, const char *header=NULL );
00093 void Ctor( const char *type, const char *base, int type_id, int flags, int size, const void *_this, const void *_base_ptr, const char *header );
00094 ~DynObjType( );
00095
00096 StructHeader _sh;
00097 const char* _type;
00098 int _type_id;
00099 short _vtbl_size;
00100 short _size;
00101 int _flags;
00102
00103
00104 DoBaseNode _base;
00105 void** _vtbl;
00106 DoCompoundNode* _compounds;
00107 DoModuleNode* _mod_fst;
00108
00109 const char* _header;
00110
00111 DoTypeItem* _pext;
00112
00113 bool IsOk();
00114
00115 bool operator == (const char *type) const { return MatchesTypeName(type); }
00116 bool operator == (void **vtbl) const { return vtbl && vtbl==_vtbl; }
00117 bool operator == (int type_id) const { return type_id==_type_id; }
00118
00119 bool IsA( int type_id, const char* pcaller_addr ) const;
00120 bool CanBeA( int type_id, const void* pobj, const char* pcaller_addr ) const;
00121 bool IsSideBase( const void *pvo ) const;
00122 bool MatchesTypeName( const char* type ) const;
00123 bool IsSameType( DynObjType* opdt ) const;
00124 bool IsSameTypeAndCompatible( DynObjType *opdt ) const;
00125 enum { AmbigEither=3, AmbigId=1, AmbigName=2 };
00126 bool IsAmbigous( int amb_type=AmbigEither ) const;
00127 int HasNestedSideBases();
00128 DynObjType *GetOuterMost( const void* pobj, int *poff=NULL ) const;
00129 DoCompoundNode* GetCompound( void** vtbl, int* poff=NULL ) const;
00130 DynObjType *GetTypeAtOffset( int off ) const;
00131
00132 DoTypeItem* LookupTypeItem( char type ) const;
00133 DoTypeItem* LookupTypeItemLinkFirst( char type );
00134 bool AddTypeItem( DoTypeItem *pitem );
00135 DoTypeItem* RemoveTypeItem( char type );
00136
00137
00138 inline void** GetKey( ){ return (void**)_vtbl; }
00139
00140 protected:
00141
00142 bool LinkAfter( DynObjType *after, bool is_name );
00143 void LinkModule( DoModuleC *pmod );
00144 void UnlinkModule( DoModuleC *pmod );
00145 DoModuleC* GetOriginalModule( );
00146
00147
00148 void *GetObj( void *pself, const char *type, DynObjType **found_type=NULL, DynObjType *pdt_avoid=NULL );
00149 void *GetObj( void *pself, int type_id, const char* pcaller, DynObjType **found_type=NULL, DynObjType *pdt_avoid=NULL );
00150
00151 bool CanBeAInternal( int type_id, const char* pcaller_addr ) const;
00152
00153
00154 bool IsTypeForCaller( const char* pcaller_addr ) const;
00155
00156 friend void* doGetObj( void *obj, const char *type, DynObjType *self_type, doCastAlgo algo, DynObjType **pdt_found );
00157 friend void* doGetObj( void *obj, int type_id, DynObjType *self_type, doCastAlgo algo, DynObjType **pdt_found );
00158 friend void* doGetObj( DynI *pdi, const char *type, doCastAlgo algo, DynObjType **pdt_found, bool internal_from_dyni );
00159
00160 friend class DoRunTimeC;
00161 friend class SideBaseDecl;
00162 };
00163
00164
00165
00166
00167
00168 class DoModuleNode {
00169 public:
00170 DoModuleNode( DoModuleC *pmod ) : _pmod(pmod), _nxt(0) { }
00171 ~DoModuleNode(){ delete _nxt; }
00172 DoModuleC *_pmod;
00173 DoModuleNode *_nxt;
00174 };
00175
00176
00177
00178 struct DoTypeItem {
00179 DoTypeItem(char item_type, char flags, DoTypeItem* nxt) { Init(item_type,flags,nxt); }
00180 ~DoTypeItem();
00181
00182 void Init( char item_type, char flags, DoTypeItem* nxt );
00183
00184 virtual void dtiDestroy(){ delete this; }
00185
00186 enum { dotiMagic=0xA9 };
00187 enum { TypeCreateDestroy=1
00188 ,TypeReplacedBy=2
00189 ,TypeAmbigLinkId=3
00190 ,TypeAmbigLinkName=4
00191 ,TypeCompundNode=5
00192 ,TypeDelayedConstruct=6
00193 ,TypeFirstCustom=128
00194 };
00195
00196 char _magic;
00197 char _item_type;
00198 char _flags;
00199 char _check_sum;
00200 DoTypeItem *_nxt;
00201
00202 bool IsOk(){ return this && _magic==(char)dotiMagic && _check_sum==(char)(_item_type^dotiMagic); }
00203 };
00204
00205
00206 class DoCompoundNode : public DoTypeItem {
00207 public:
00208
00209 DoCompoundNode( void** vtbl, DynObjType* compound, DynObjType* user );
00210 virtual void dtiDestroy();
00211 DoCompoundNode *GetCompound( void** vtbl, int* poff, const DynObjType *ptd_from );
00212
00213 DynObjType *_user;
00214 DynObjType *_compound;
00215 void **_vtbl;
00216 DoCompoundNode *_nxt_compound;
00217
00218
00219 int _type_id_lookup;
00220 DynObjType *_pdt_lookup;
00221 };
00222
00223
00224
00225
00226 struct DoReplacedByItem : public DoTypeItem {
00227 DoReplacedByItem( DynObjType *pdt_replaced_by )
00228 : DoTypeItem(DoTypeItem::TypeReplacedBy,0,NULL),
00229 _pdt_replaced_by(pdt_replaced_by) { }
00230 DynObjType* _pdt_replaced_by;
00231 };
00232
00233
00234
00235 struct DelayedConstruct : public DoTypeItem {
00236 DelayedConstruct( const void* pobj )
00237 : DoTypeItem(TypeDelayedConstruct,0,NULL),
00238 _pobj(pobj) { }
00239 const void *_pobj;
00240 };
00241
00242
00243 #ifdef DO_IMPLEMENTING
00244
00245
00246
00247 #define DOT_DESTROY_SOFT 2 // For DynObj type, in a sub object, set DoDostroy to harmless method
00248 #define DOT_USER_TYPE 4 // A user type (not internal, abstract or side base). Can be instantiated.
00249 #define DOT_NO_VTABLE_CORR 8 // Do not correct VTable for this type
00250 #define DOT_STATIC_TYPE 16 // Instances of this type are static
00251
00252
00253 #define DOT_HAS_NESTED_SIDE_BASE 0x0100 // This type, or one of its bases has a side base class
00254 #define DOT_TESTED_NESTED_SIDE_BASE 0x0200 // After we know above, set this flag
00255 #define DOT_DORT_MERGED 0x0400 // Merged with doRunTime type database
00256 #define DOT_DID_INIT 0x0800 // Type initialized & registered (after calling doConstruct & DORT.RegisterType)
00257 #define DOT_CONST_STRINGS 0x1000 // Type strings are not allocated
00258 #define DOT_REPLACED_BY 0x2000 // Type has been replaced by other type (previously loaded)
00259 #define DOT_IS_AMBIGOUS_ID 0x4000 // This type is ambigous (several share the same type ID or type name)
00260 #define DOT_IS_AMBIGOUS_NAME 0x8000 // This type is ambigous (several share the same type ID or type name)
00261
00262 #define DOT_ALIVE 0x80800000 // Value to check that type is "alive"
00263 #define DOT_ALIVE_MASK 0xC0C00000 // Mask to check that type is "alive"
00264 #define DOT_CLEAR_IN_CTOR 0xFF00
00265
00266 #if DO_ENABLE_VTABLE_CORR==1
00267 #include "DoVTableInfo.hpp"
00268 #endif
00269
00270
00271
00272 template<class T>
00273 void* VObjTempInstance( int *pvts ){
00274 #if DO_ENABLE_VTABLE_CORR==1
00275 if( pvts ) *pvts = GetVTableSizeOf<T,void>();
00276 #endif
00277 T* pt = new T;
00278 return pt;
00279 }
00280
00281 template<class T>
00282 void VObjTempInstanceDelete( void *pv ){
00283 ::delete (T*)pv;
00284 }
00285
00286
00287 class DynI;
00288 template<class T>
00289 void* DynObjTempInstance( int *pvts ){
00290 #if DO_ENABLE_VTABLE_CORR==1
00291 if( pvts ) *pvts = GetVTableSizeOf<T,DynI*>();
00292 #endif
00293 return new T((DynI*)NULL);
00294 }
00295
00296
00297
00298 struct DoCreateDestroyItem : public DoTypeItem {
00299 DoCreateDestroyItem( CreateVObjFn cfn, DestroyVObjFn dfn )
00300 : DoTypeItem(DoTypeItem::TypeCreateDestroy,0,NULL),
00301 _cfn(cfn), _dfn(dfn) { }
00302 CreateVObjFn _cfn;
00303 DestroyVObjFn _dfn;
00304 };
00305
00306
00307
00308
00309
00310
00311
00312
00313 template<class MainCl, class BaseCl=void, bool is_dynobj=false>
00314 class DynObjTypeI2R;
00315
00316
00317 template<class MainCl, class BaseCl>
00318 class DynObjTypeI2R<MainCl,BaseCl,true> : public DynObjType {
00319 public:
00320 DynObjTypeI2R( const char *type, int type_id, int flags, const char *header=NULL )
00321 : DynObjType( type, type_id, flags, sizeof(MainCl), NULL,NULL, header ) {
00322 DoCreateDestroyItem *pit = new DoCreateDestroyItem(
00323 (CreateVObjFn)DynObjTempInstance<MainCl>,
00324 VObjTempInstanceDelete<MainCl> );
00325 AddTypeItem(pit);
00326
00327
00328
00329
00330
00331
00332
00333
00334 }
00335 };
00336
00337
00338 template<class MainCl, class BaseCl>
00339 class DynObjTypeI2R<MainCl,BaseCl,false> : public DynObjType {
00340 public:
00341 DynObjTypeI2R( const char *type, int type_id, int ver, const char *header=NULL )
00342 : DynObjType( type, type_id, 0, sizeof(MainCl), NULL,NULL, header ) {
00343 DoCreateDestroyItem *pit = new DoCreateDestroyItem(
00344 VObjTempInstance<MainCl>,
00345 VObjTempInstanceDelete<MainCl> );
00346 AddTypeItem(pit);
00347 }
00348 };
00349
00350
00351
00352
00353 template <class Base, class SideBase>
00354 int sidebase_offset( const Base *pb=NULL ){
00355
00356
00357
00358 if( !pb ) pb = reinterpret_cast<const Base*>(&pb);
00359 const SideBase *pcb = static_cast<const SideBase*>(pb);
00360 return (int)(reinterpret_cast<const char*>(pcb) - reinterpret_cast<const char*>(pb));
00361 }
00362
00363
00364
00365 class SideBaseDecl : public DoBaseNode {
00366 public:
00367 SideBaseDecl( const char *main_cl, const char *side_base_cl, int size, int offset, const void *_this, int vtbl_size, void **vtbl_o );
00368 void Ctor( const char *main_cl, const char *side_base_cl, int size, int offset, const void *_this, int vtbl_size, void **vtbl_o );
00369 const char* _main_cl;
00370 };
00371
00372
00373 #define DO_ADD_SIDE_BASE(MainCl,SideBaseCl)\
00374 SideBaseDecl g_sbd_##MainCl##SideBaseCl( #MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(),NULL,GetVTableSizeOf<SideBaseCl>(),GetVTableOf<SideBaseCl>() )
00375
00376
00377
00378
00379 #define DO_ADD_SIDE_BASE_THIS(MainCl,SideBaseCl) { \
00380 this->SideBaseCl::doGetType( const DynI **pself=0 ); \
00381 static SideBaseDecl sbdt(#MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(this),this,-1,NULL); \
00382 }
00383
00384
00385
00386
00387 #define DO_ADD_SIDE_BASE_THIS_VTABLE_CORR(MainCl,SideBaseCl) { \
00388 this->SideBaseCl::doGetType( const DynI **pself=0 ); \
00389 static SideBaseDecl sbdt(#MainCl,#SideBaseCl,sizeof(SideBaseCl),sidebase_offset<MainCl,SideBaseCl>(this),this,GetVTableSizeOf<SideBaseCl>(),GetVTableOf<SideBaseCl>()); \
00390 }
00391
00392 #endif // DO_IMPLEMENTING
00393
00394
00395 #endif // DOTYPE_H
00396
00397