rtti.inc 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1999-2000 by Michael Van Canneyt
  5. member of the Free Pascal development team
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. { Run-Time type information routines }
  13. { The RTTI is implemented through a series of constants : }
  14. Const
  15. tkUnknown = 0;
  16. tkInteger = 1;
  17. tkChar = 2;
  18. tkEnumeration = 3;
  19. tkFloat = 4;
  20. tkSet = 5;
  21. tkMethod = 6;
  22. tkSString = 7;
  23. tkString = tkSString;
  24. tkLString = 8;
  25. tkAString = 9;
  26. tkWString = 10;
  27. tkVariant = 11;
  28. tkArray = 12;
  29. tkRecord = 13;
  30. tkInterface = 14;
  31. tkClass = 15;
  32. tkObject = 16;
  33. tkWChar = 17;
  34. tkBool = 18;
  35. tkInt64 = 19;
  36. tkQWord = 20;
  37. tkDynArray = 21;
  38. { A record is designed as follows :
  39. 1 : tkrecord
  40. 2 : Length of name string (n);
  41. 3 : name string;
  42. 3+n : record size;
  43. 7+n : number of elements (N)
  44. 11+n : N times : Pointer to type info
  45. Offset in record
  46. }
  47. Type
  48. TRecElem = Record
  49. Info : Pointer;
  50. Offset : Longint;
  51. end;
  52. TRecElemArray = Array[1..Maxint] of TRecElem;
  53. PRecRec = ^TRecRec;
  54. TRecRec = record
  55. Size,Count : Longint;
  56. Elements : TRecElemArray;
  57. end;
  58. { An array is designed as follows :
  59. 1 : tkArray;
  60. 2 : length of name string (n);
  61. 3 : NAme string
  62. 3+n : Element Size
  63. 7+n : Number of elements
  64. 11+n : Pointer to type of elements
  65. }
  66. PArrayRec = ^TArrayRec;
  67. TArrayRec = record
  68. Size,Count : Longint;
  69. Info : Pointer;
  70. end;
  71. Procedure fpc_Initialize (Data,TypeInfo : pointer);saveregisters;[Public,Alias : 'FPC_INITIALIZE']; {$ifdef hascompilerproc} compilerproc; {$endif}
  72. { this definition is sometimes (depending on switches)
  73. already defined or not so define it locally to avoid problems PM }
  74. Type
  75. Pbyte = ^Byte;
  76. Var Temp : PByte;
  77. I : longint;
  78. Size,Count : longint;
  79. TInfo : Pointer;
  80. begin
  81. Temp:=PByte(TypeInfo);
  82. case temp^ of
  83. tkAstring,tkWstring,tkInterface,tkDynArray:
  84. PPchar(Data)^:=Nil;
  85. tkArray:
  86. begin
  87. inc(temp);
  88. I:=temp^;
  89. inc(temp,(I+1)); // skip name string;
  90. Size:=PArrayRec(Temp)^.Size; // get element size
  91. Count:=PArrayRec(Temp)^.Count; // get element Count
  92. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  93. For I:=0 to Count-1 do
  94. int_Initialize (Data+(I*size),TInfo);
  95. end;
  96. tkRecord,tkClass,tkObject:
  97. begin
  98. inc(Temp);
  99. I:=Temp^;
  100. inc(temp,I+1); // skip name string;
  101. { if it isn't necessary, why should we load it ? FK
  102. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  103. }
  104. Count:=PRecRec(Temp)^.Count; // get element Count
  105. For I:=1 to count Do
  106. With PRecRec(Temp)^.elements[I] do
  107. int_Initialize (Data+Offset,Info);
  108. end;
  109. {$ifdef HASVARIANT}
  110. tkVariant:
  111. variant_init(Variant(PVarData(Data)^))
  112. {$endif HASVARIANT}
  113. end;
  114. end;
  115. Procedure fpc_finalize (Data,TypeInfo: Pointer);saveregisters;[Public,Alias : 'FPC_FINALIZE']; {$ifdef hascompilerproc} compilerproc; {$endif}
  116. { this definition is sometimes (depending on switches)
  117. already defined or not so define it locally to avoid problems PM }
  118. Type
  119. Pbyte = ^Byte;
  120. PPointer = ^Pointer;
  121. Var Temp : PByte;
  122. I : longint;
  123. Size,Count : longint;
  124. TInfo : Pointer;
  125. begin
  126. Temp:=PByte(TypeInfo);
  127. case temp^ of
  128. tkAstring :
  129. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  130. {$ifdef HASWIDESTRING}
  131. tkWstring :
  132. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  133. {$endif HASWIDESTRING}
  134. tkArray :
  135. begin
  136. inc(Temp);
  137. I:=temp^;
  138. inc(temp,I+1); // skip name string;
  139. Size:=PArrayRec(Temp)^.Size; // get element size
  140. Count:=PArrayRec(Temp)^.Count; // get element Count
  141. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  142. For I:=0 to Count-1 do
  143. int_Finalize (Data+(I*size),TInfo);
  144. end;
  145. tkRecord,tkObject,tkClass:
  146. begin
  147. inc(Temp);
  148. I:=Temp^;
  149. inc(temp,I+1); // skip name string;
  150. { if it isn't necessary, why should we load it? FK
  151. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  152. }
  153. Count:=PRecRec(Temp)^.Count; // get element Count
  154. For I:=1 to count do
  155. With PRecRec(Temp)^.elements[I] do
  156. int_Finalize (Data+Offset,Info);
  157. end;
  158. {$ifdef HASINTF}
  159. tkInterface:
  160. Intf_Decr_Ref(PPointer(Data)^);
  161. {$endif HASINTF}
  162. tkDynArray:
  163. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  164. {$ifdef HASVARIANT}
  165. tkVariant:
  166. variant_clear(Variant(PVarData(Data)^))
  167. {$endif HASVARIANT}
  168. end;
  169. end;
  170. Procedure fpc_Addref (Data,TypeInfo : Pointer);saveregisters; [Public,alias : 'FPC_ADDREF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  171. { this definition is sometimes (depending on switches)
  172. already defined or not so define it locally to avoid problems PM }
  173. Type
  174. Pbyte = ^Byte;
  175. PPointer = ^Pointer;
  176. Var Temp : PByte;
  177. I : longint;
  178. Size,Count : longint;
  179. TInfo : Pointer;
  180. begin
  181. Temp:=PByte(TypeInfo);
  182. case temp^ of
  183. tkAstring :
  184. fpc_AnsiStr_Incr_Ref(PPointer(Data)^);
  185. {$ifdef HASWIDESTRING}
  186. tkWstring :
  187. fpc_WideStr_Incr_Ref(PPointer(Data)^);
  188. {$endif HASWIDESTRING}
  189. tkArray :
  190. begin
  191. Inc(Temp);
  192. I:=temp^;
  193. inc(temp,I+1); // skip name string;
  194. Size:=PArrayRec(Temp)^.Size; // get element size
  195. Count:=PArrayRec(Temp)^.Count; // get element Count
  196. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  197. For I:=0 to Count-1 do
  198. int_AddRef (Data+(I*size),TInfo);
  199. end;
  200. tkrecord :
  201. begin
  202. Inc(Temp);
  203. I:=Temp^;
  204. temp:=temp+(I+1); // skip name string;
  205. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  206. Count:=PRecRec(Temp)^.Count; // get element Count
  207. For I:=1 to count do
  208. With PRecRec(Temp)^.elements[I] do
  209. int_AddRef (Data+Offset,Info);
  210. end;
  211. tkDynArray:
  212. fpc_dynarray_incr_ref(PPointer(Data)^);
  213. {$ifdef HASINTF}
  214. tkInterface:
  215. Intf_Incr_Ref(PPointer(Data)^);
  216. {$endif HASINTF}
  217. end;
  218. end;
  219. { alias for internal use }
  220. { we use another name else the compiler gets puzzled because of the wrong forward def }
  221. procedure fpc_systemDecRef (Data, TypeInfo : Pointer);saveregisters;[external name 'FPC_DECREF'];
  222. Procedure fpc_DecRef (Data, TypeInfo : Pointer);saveregisters;[Public,alias : 'FPC_DECREF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  223. { this definition is sometimes (depending on switches)
  224. already defined or not so define it locally to avoid problems PM }
  225. Type
  226. Pbyte = ^Byte;
  227. PPointer = ^Pointer;
  228. Var Temp : PByte;
  229. I : longint;
  230. Size,Count : longint;
  231. TInfo : Pointer;
  232. begin
  233. Temp:=PByte(TypeInfo);
  234. case temp^ of
  235. { see AddRef for comment about below construct (JM) }
  236. tkAstring:
  237. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  238. {$ifdef HASWIDESTRING}
  239. tkWstring:
  240. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  241. {$endif HASWIDESTRING}
  242. tkArray:
  243. begin
  244. inc(Temp);
  245. I:=temp^;
  246. inc(temp,I+1); // skip name string;
  247. Size:=PArrayRec(Temp)^.Size; // get element size
  248. Count:=PArrayRec(Temp)^.Count; // get element Count
  249. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  250. For I:=0 to Count-1 do
  251. fpc_systemDecRef (Data+(I*size),TInfo);
  252. end;
  253. tkrecord:
  254. begin
  255. Temp:=Temp+1;
  256. I:=Temp^;
  257. temp:=temp+(I+1); // skip name string;
  258. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  259. Count:=PRecRec(Temp)^.Count; // get element Count
  260. For I:=1 to count do
  261. With PRecRec(Temp)^.elements[I] do
  262. fpc_systemDecRef (Data+Offset,Info);
  263. end;
  264. tkDynArray:
  265. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  266. {$ifdef HASINTF}
  267. tkInterface:
  268. Intf_Decr_Ref(PPointer(Data)^);
  269. {$endif HASINTF}
  270. end;
  271. end;
  272. procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); [Public,Alias:'FPC_FINALIZEARRAY']; {$ifdef hascompilerproc} compilerproc; {$endif}
  273. var
  274. i : longint;
  275. begin
  276. for i:=0 to count-1 do
  277. int_finalize(data+size*i,typeinfo);
  278. end;
  279. {
  280. $Log$
  281. Revision 1.6 2002-09-02 18:42:41 peter
  282. * moved genrtti.inc code to rtti
  283. * removed rttip.inc, the generic code is almost as fast and
  284. much easier to maintain and has less risks on bugs
  285. Revision 1.5 2001/11/17 16:56:08 florian
  286. * init and final code in genrtti.inc updated
  287. Revision 1.4 2001/04/23 18:25:45 peter
  288. * m68k updates
  289. Revision 1.3 2000/10/21 18:20:17 florian
  290. * a lot of small changes:
  291. - setlength is internal
  292. - win32 graph unit extended
  293. ....
  294. Revision 1.2 2000/07/13 11:33:45 michael
  295. + removed logs
  296. }