rtti.inc 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 1999-2000 by Michael Van Canneyt
  4. member of the Free Pascal development team
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. { Run-Time type information routines }
  12. { The RTTI is implemented through a series of constants : }
  13. Const
  14. tkUnknown = 0;
  15. tkInteger = 1;
  16. tkChar = 2;
  17. tkEnumeration = 3;
  18. tkFloat = 4;
  19. tkSet = 5;
  20. tkMethod = 6;
  21. tkSString = 7;
  22. tkString = tkSString;
  23. tkLString = 8;
  24. tkAString = 9;
  25. tkWString = 10;
  26. tkVariant = 11;
  27. tkArray = 12;
  28. tkRecord = 13;
  29. tkInterface = 14;
  30. tkClass = 15;
  31. tkObject = 16;
  32. tkWChar = 17;
  33. tkBool = 18;
  34. tkInt64 = 19;
  35. tkQWord = 20;
  36. tkDynArray = 21;
  37. type
  38. TRTTIProc=procedure(Data,TypeInfo:Pointer);
  39. procedure RecordRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
  40. {
  41. A record is designed as follows :
  42. 1 : tkrecord
  43. 2 : Length of name string (n);
  44. 3 : name string;
  45. 3+n : record size;
  46. 7+n : number of elements (N)
  47. 11+n : N times : Pointer to type info
  48. Offset in record
  49. }
  50. var
  51. Temp : pbyte;
  52. namelen : byte;
  53. count,
  54. offset,
  55. i : longint;
  56. info : pointer;
  57. begin
  58. Temp:=PByte(TypeInfo);
  59. inc(Temp);
  60. { Skip Name }
  61. namelen:=Temp^;
  62. inc(temp,namelen+1);
  63. temp:=aligntoptr(temp);
  64. { Skip size }
  65. inc(Temp,4);
  66. { Element count }
  67. Count:=PLongint(Temp)^;
  68. inc(Temp,sizeof(Count));
  69. { Process elements }
  70. for i:=1 to count Do
  71. begin
  72. Info:=PPointer(Temp)^;
  73. inc(Temp,sizeof(Info));
  74. Offset:=PLongint(Temp)^;
  75. inc(Temp,sizeof(Offset));
  76. rttiproc (Data+Offset,Info);
  77. end;
  78. end;
  79. procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
  80. {
  81. An array is designed as follows :
  82. 1 : tkArray;
  83. 2 : length of name string (n);
  84. 3 : NAme string
  85. 3+n : Element Size
  86. 7+n : Number of elements
  87. 11+n : Pointer to type of elements
  88. }
  89. var
  90. Temp : pbyte;
  91. namelen : byte;
  92. count,
  93. size,
  94. i : SizeInt;
  95. info : pointer;
  96. begin
  97. Temp:=PByte(TypeInfo);
  98. inc(Temp);
  99. { Skip Name }
  100. namelen:=Temp^;
  101. inc(temp,namelen+1);
  102. temp:=aligntoptr(temp);
  103. { Element size }
  104. size:=PSizeInt(Temp)^;
  105. inc(Temp,sizeof(Size));
  106. { Element count }
  107. Count:=PSizeInt(Temp)^;
  108. inc(Temp,sizeof(Count));
  109. Info:=PPointer(Temp)^;
  110. inc(Temp,sizeof(Info));
  111. { Process elements }
  112. for I:=0 to Count-1 do
  113. rttiproc(Data+(I*size),Info);
  114. end;
  115. Procedure fpc_Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE']; compilerproc;
  116. begin
  117. case PByte(TypeInfo)^ of
  118. tkAstring,tkWstring,tkInterface,tkDynArray:
  119. PPchar(Data)^:=Nil;
  120. tkArray:
  121. arrayrtti(data,typeinfo,@int_initialize);
  122. tkObject,
  123. tkRecord:
  124. recordrtti(data,typeinfo,@int_initialize);
  125. tkVariant:
  126. variant_init(PVarData(Data)^);
  127. end;
  128. end;
  129. Procedure fpc_finalize (Data,TypeInfo: Pointer);[Public,Alias : 'FPC_FINALIZE']; compilerproc;
  130. begin
  131. case PByte(TypeInfo)^ of
  132. tkAstring :
  133. begin
  134. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  135. PPointer(Data)^:=nil;
  136. end;
  137. tkWstring :
  138. begin
  139. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  140. PPointer(Data)^:=nil;
  141. end;
  142. tkArray :
  143. arrayrtti(data,typeinfo,@int_finalize);
  144. tkObject,
  145. tkRecord:
  146. recordrtti(data,typeinfo,@int_finalize);
  147. tkInterface:
  148. begin
  149. Intf_Decr_Ref(PPointer(Data)^);
  150. PPointer(Data)^:=nil;
  151. end;
  152. tkDynArray:
  153. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  154. tkVariant:
  155. variant_clear(PVarData(Data)^);
  156. end;
  157. end;
  158. Procedure fpc_Addref (Data,TypeInfo : Pointer); [Public,alias : 'FPC_ADDREF']; compilerproc;
  159. begin
  160. case PByte(TypeInfo)^ of
  161. tkAstring :
  162. fpc_AnsiStr_Incr_Ref(PPointer(Data)^);
  163. tkWstring :
  164. fpc_WideStr_Incr_Ref(PPointer(Data)^);
  165. tkArray :
  166. arrayrtti(data,typeinfo,@int_addref);
  167. tkobject,
  168. tkrecord :
  169. recordrtti(data,typeinfo,@int_addref);
  170. tkDynArray:
  171. fpc_dynarray_incr_ref(PPointer(Data)^);
  172. tkInterface:
  173. Intf_Incr_Ref(PPointer(Data)^);
  174. tkVariant:
  175. variant_addref(pvardata(Data)^);
  176. end;
  177. end;
  178. { alias for internal use }
  179. { we use another name else the compiler gets puzzled because of the wrong forward def }
  180. procedure fpc_systemDecRef (Data, TypeInfo : Pointer);[external name 'FPC_DECREF'];
  181. Procedure fpc_DecRef (Data, TypeInfo : Pointer);[Public,alias : 'FPC_DECREF']; compilerproc;
  182. begin
  183. case PByte(TypeInfo)^ of
  184. { see AddRef for comment about below construct (JM) }
  185. tkAstring:
  186. fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
  187. tkWstring:
  188. fpc_WideStr_Decr_Ref(PPointer(Data)^);
  189. tkArray:
  190. arrayrtti(data,typeinfo,@fpc_systemDecRef);
  191. tkobject,
  192. tkrecord:
  193. recordrtti(data,typeinfo,@fpc_systemDecRef);
  194. tkDynArray:
  195. fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
  196. tkInterface:
  197. Intf_Decr_Ref(PPointer(Data)^);
  198. tkVariant:
  199. variant_clear(pvardata(data)^);
  200. end;
  201. end;
  202. (*
  203. Procedure fpc_Copy (Src, Dest, TypeInfo : Pointer);[Public,alias : 'FPC_COPY']; compilerproc;
  204. var
  205. Temp : pbyte;
  206. namelen : byte;
  207. count,
  208. offset,
  209. i : longint;
  210. info : pointer;
  211. begin
  212. case PByte(TypeInfo)^ of
  213. tkAstring:
  214. begin
  215. fpc_AnsiStr_Incr_Ref(PPointer(Src)^);
  216. fpc_AnsiStr_Decr_Ref(PPointer(Dest)^);
  217. PPointer(Dest)^:=PPointer(Src)^;
  218. end;
  219. tkWstring:
  220. begin
  221. fpc_WideStr_Incr_Ref(PPointer(Src)^);
  222. fpc_WideStr_Decr_Ref(PPointer(Dest)^);
  223. end;
  224. tkArray:
  225. begin
  226. arrayrtti(data,typeinfo,@fpc_systemDecRef);
  227. end;
  228. tkobject,
  229. tkrecord:
  230. begin
  231. Temp:=PByte(TypeInfo);
  232. inc(Temp);
  233. { Skip Name }
  234. namelen:=Temp^;
  235. inc(temp,namelen+1);
  236. temp:=aligntoptr(temp);
  237. { copy data }
  238. move(src^,dest^,plongint(temp)^);
  239. { Skip size }
  240. inc(Temp,4);
  241. { Element count }
  242. Count:=PLongint(Temp)^;
  243. inc(Temp,sizeof(Count));
  244. { Process elements }
  245. for i:=1 to count Do
  246. begin
  247. Info:=PPointer(Temp)^;
  248. inc(Temp,sizeof(Info));
  249. Offset:=PLongint(Temp)^;
  250. inc(Temp,sizeof(Offset));
  251. fpc_Copy(Src+Offset,Src+Offset,Info);
  252. end;
  253. tkDynArray:
  254. begin
  255. fpc_dynarray_Incr_Ref(PPointer(Src)^);
  256. fpc_dynarray_Decr_Ref(PPointer(Dest)^);
  257. PPointer(Dest)^:=PPointer(Src)^;
  258. end;
  259. tkInterface:
  260. begin
  261. Intf_Incr_Ref(PPointer(Src)^);
  262. Intf_Decr_Ref(PPointer(Dest)^);
  263. PPointer(Dest)^:=PPointer(Src)^;
  264. end;
  265. tkVariant:
  266. VarCopyProc(pvardata(dest)^,pvardata(src)^);
  267. end;
  268. end;
  269. *)
  270. procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); [Public,Alias:'FPC_FINALIZEARRAY']; compilerproc;
  271. var
  272. i : longint;
  273. begin
  274. for i:=0 to count-1 do
  275. int_finalize(data+size*i,typeinfo);
  276. end;