rtti.inc 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  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. begin
  130. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  131. PPchar(Data)^:=Nil;
  132. end;
  133. {$ifdef HASWIDESTRING}
  134. tkWstring :
  135. begin
  136. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  137. PPchar(Data)^:=Nil;
  138. end;
  139. {$endif HASWIDESTRING}
  140. tkArray :
  141. begin
  142. inc(Temp);
  143. I:=temp^;
  144. inc(temp,I+1); // skip name string;
  145. Size:=PArrayRec(Temp)^.Size; // get element size
  146. Count:=PArrayRec(Temp)^.Count; // get element Count
  147. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  148. For I:=0 to Count-1 do
  149. int_Finalize (Data+(I*size),TInfo);
  150. end;
  151. tkRecord,tkObject,tkClass:
  152. begin
  153. inc(Temp);
  154. I:=Temp^;
  155. inc(temp,I+1); // skip name string;
  156. { if it isn't necessary, why should we load it? FK
  157. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  158. }
  159. Count:=PRecRec(Temp)^.Count; // get element Count
  160. For I:=1 to count do
  161. With PRecRec(Temp)^.elements[I] do
  162. int_Finalize (Data+Offset,Info);
  163. end;
  164. {$ifdef HASINTF}
  165. tkInterface:
  166. Intf_Decr_Ref(PPointer(Data)^);
  167. {$endif HASINTF}
  168. tkDynArray:
  169. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  170. {$ifdef HASVARIANT}
  171. tkVariant:
  172. variant_clear(Variant(PVarData(Data)^))
  173. {$endif HASVARIANT}
  174. end;
  175. end;
  176. Procedure fpc_Addref (Data,TypeInfo : Pointer);saveregisters; [Public,alias : 'FPC_ADDREF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  177. { this definition is sometimes (depending on switches)
  178. already defined or not so define it locally to avoid problems PM }
  179. Type
  180. Pbyte = ^Byte;
  181. PPointer = ^Pointer;
  182. Var Temp : PByte;
  183. I : longint;
  184. Size,Count : longint;
  185. TInfo : Pointer;
  186. begin
  187. Temp:=PByte(TypeInfo);
  188. case temp^ of
  189. tkAstring :
  190. fpc_AnsiStr_Incr_Ref(PPointer(Data)^);
  191. {$ifdef HASWIDESTRING}
  192. tkWstring :
  193. fpc_WideStr_Incr_Ref(PPointer(Data)^);
  194. {$endif HASWIDESTRING}
  195. tkArray :
  196. begin
  197. Inc(Temp);
  198. I:=temp^;
  199. inc(temp,I+1); // skip name string;
  200. Size:=PArrayRec(Temp)^.Size; // get element size
  201. Count:=PArrayRec(Temp)^.Count; // get element Count
  202. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  203. For I:=0 to Count-1 do
  204. int_AddRef (Data+(I*size),TInfo);
  205. end;
  206. tkrecord :
  207. begin
  208. Inc(Temp);
  209. I:=Temp^;
  210. temp:=temp+(I+1); // skip name string;
  211. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  212. Count:=PRecRec(Temp)^.Count; // get element Count
  213. For I:=1 to count do
  214. With PRecRec(Temp)^.elements[I] do
  215. int_AddRef (Data+Offset,Info);
  216. end;
  217. tkDynArray:
  218. fpc_dynarray_incr_ref(PPointer(Data)^);
  219. {$ifdef HASINTF}
  220. tkInterface:
  221. Intf_Incr_Ref(PPointer(Data)^);
  222. {$endif HASINTF}
  223. end;
  224. end;
  225. { alias for internal use }
  226. { we use another name else the compiler gets puzzled because of the wrong forward def }
  227. procedure fpc_systemDecRef (Data, TypeInfo : Pointer);saveregisters;[external name 'FPC_DECREF'];
  228. Procedure fpc_DecRef (Data, TypeInfo : Pointer);saveregisters;[Public,alias : 'FPC_DECREF']; {$ifdef hascompilerproc} compilerproc; {$endif}
  229. { this definition is sometimes (depending on switches)
  230. already defined or not so define it locally to avoid problems PM }
  231. Type
  232. Pbyte = ^Byte;
  233. PPointer = ^Pointer;
  234. Var Temp : PByte;
  235. I : longint;
  236. Size,Count : longint;
  237. TInfo : Pointer;
  238. begin
  239. Temp:=PByte(TypeInfo);
  240. case temp^ of
  241. { see AddRef for comment about below construct (JM) }
  242. tkAstring:
  243. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  244. {$ifdef HASWIDESTRING}
  245. tkWstring:
  246. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  247. {$endif HASWIDESTRING}
  248. tkArray:
  249. begin
  250. inc(Temp);
  251. I:=temp^;
  252. inc(temp,I+1); // skip name string;
  253. Size:=PArrayRec(Temp)^.Size; // get element size
  254. Count:=PArrayRec(Temp)^.Count; // get element Count
  255. TInfo:=PArrayRec(Temp)^.Info; // Get element info
  256. For I:=0 to Count-1 do
  257. fpc_systemDecRef (Data+(I*size),TInfo);
  258. end;
  259. tkrecord:
  260. begin
  261. Temp:=Temp+1;
  262. I:=Temp^;
  263. temp:=temp+(I+1); // skip name string;
  264. Size:=PRecRec(Temp)^.Size; // get record size; not needed.
  265. Count:=PRecRec(Temp)^.Count; // get element Count
  266. For I:=1 to count do
  267. With PRecRec(Temp)^.elements[I] do
  268. fpc_systemDecRef (Data+Offset,Info);
  269. end;
  270. tkDynArray:
  271. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  272. {$ifdef HASINTF}
  273. tkInterface:
  274. Intf_Decr_Ref(PPointer(Data)^);
  275. {$endif HASINTF}
  276. end;
  277. end;
  278. procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); [Public,Alias:'FPC_FINALIZEARRAY']; {$ifdef hascompilerproc} compilerproc; {$endif}
  279. var
  280. i : longint;
  281. begin
  282. for i:=0 to count-1 do
  283. int_finalize(data+size*i,typeinfo);
  284. end;
  285. {
  286. $Log$
  287. Revision 1.8 2004-01-22 22:09:05 peter
  288. * finalize needs to reset to nil after decr_ref
  289. Revision 1.7 2002/09/07 15:07:46 peter
  290. * old logs removed and tabs fixed
  291. Revision 1.6 2002/09/02 18:42:41 peter
  292. * moved genrtti.inc code to rtti
  293. * removed rttip.inc, the generic code is almost as fast and
  294. much easier to maintain and has less risks on bugs
  295. }