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
6
See the file COPYING.FPC, included in this distribution,
7
for details about the copyright.
9
This program is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
**********************************************************************}
15
{ Run-Time type information routines }
17
{ The RTTI is implemented through a series of constants : }
46
TRTTIProc=procedure(Data,TypeInfo:Pointer);
48
{ if you modify this procedure, fpc_copy must be probably modified as well }
49
procedure RecordRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
51
A record is designed as follows :
53
2 : Length of name string (n);
56
7+n : number of elements (N)
57
11+n : N times : Pointer to type info
68
Temp:=PByte(TypeInfo);
73
temp:=aligntoptr(temp);
77
Count:=PLongint(Temp)^;
78
inc(Temp,sizeof(Count));
82
Info:=PPointer(Temp)^;
83
inc(Temp,sizeof(Info));
84
Offset:=PLongint(Temp)^;
85
inc(Temp,sizeof(Offset));
86
rttiproc (Data+Offset,Info);
91
{ if you modify this procedure, fpc_copy must be probably modified as well }
92
procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
94
An array is designed as follows :
96
2 : length of name string (n);
99
7+n : Number of elements
100
11+n : Pointer to type of elements
110
Temp:=PByte(TypeInfo);
115
temp:=aligntoptr(temp);
117
size:=PSizeInt(Temp)^;
118
inc(Temp,sizeof(Size));
120
Count:=PSizeInt(Temp)^;
121
inc(Temp,sizeof(Count));
122
Info:=PPointer(Temp)^;
123
inc(Temp,sizeof(Info));
125
for I:=0 to Count-1 do
126
rttiproc(Data+(I*size),Info);
130
Procedure fpc_Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE']; compilerproc;
132
case PByte(TypeInfo)^ of
133
tkAstring,tkWstring,tkInterface,tkDynArray:
136
arrayrtti(data,typeinfo,@int_initialize);
139
recordrtti(data,typeinfo,@int_initialize);
141
variant_init(PVarData(Data)^);
146
Procedure fpc_finalize (Data,TypeInfo: Pointer);[Public,Alias : 'FPC_FINALIZE']; compilerproc;
148
case PByte(TypeInfo)^ of
151
fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
152
PPointer(Data)^:=nil;
156
fpc_WideStr_Decr_Ref(PPointer(Data)^);
157
PPointer(Data)^:=nil;
160
arrayrtti(data,typeinfo,@int_finalize);
163
recordrtti(data,typeinfo,@int_finalize);
166
Intf_Decr_Ref(PPointer(Data)^);
167
PPointer(Data)^:=nil;
170
fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
172
variant_clear(PVarData(Data)^);
177
Procedure fpc_Addref (Data,TypeInfo : Pointer); [Public,alias : 'FPC_ADDREF']; compilerproc;
179
case PByte(TypeInfo)^ of
181
fpc_AnsiStr_Incr_Ref(PPointer(Data)^);
183
fpc_WideStr_Incr_Ref(PPointer(Data)^);
185
arrayrtti(data,typeinfo,@int_addref);
188
recordrtti(data,typeinfo,@int_addref);
190
fpc_dynarray_incr_ref(PPointer(Data)^);
192
Intf_Incr_Ref(PPointer(Data)^);
194
variant_addref(pvardata(Data)^);
199
{ alias for internal use }
200
{ we use another name else the compiler gets puzzled because of the wrong forward def }
201
procedure fpc_systemDecRef (Data, TypeInfo : Pointer);[external name 'FPC_DECREF'];
203
Procedure fpc_DecRef (Data, TypeInfo : Pointer);[Public,alias : 'FPC_DECREF']; compilerproc;
205
case PByte(TypeInfo)^ of
206
{ see AddRef for comment about below construct (JM) }
208
fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
210
fpc_WideStr_Decr_Ref(PPointer(Data)^);
212
arrayrtti(data,typeinfo,@fpc_systemDecRef);
215
recordrtti(data,typeinfo,@fpc_systemDecRef);
217
fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
219
Intf_Decr_Ref(PPointer(Data)^);
221
variant_clear(pvardata(data)^);
225
{ define alias for internal use in the system unit }
226
Function fpc_Copy_internal (Src, Dest, TypeInfo : Pointer) : SizeInt;[external name 'FPC_COPY'];
228
Function fpc_Copy (Src, Dest, TypeInfo : Pointer) : SizeInt;[Public,alias : 'FPC_COPY']; compilerproc;
240
result:=sizeof(pointer);
241
case PByte(TypeInfo)^ of
244
fpc_AnsiStr_Incr_Ref(PPointer(Src)^);
245
fpc_AnsiStr_Decr_Ref(PPointer(Dest)^);
246
PPointer(Dest)^:=PPointer(Src)^;
249
fpc_WideStr_Assign(PPointer(Dest)^,PPointer(Src)^);
252
Temp:=PByte(TypeInfo);
257
temp:=aligntoptr(temp);
260
size:=PSizeInt(Temp)^;
261
inc(Temp,sizeof(Size));
264
Count:=PSizeInt(Temp)^;
265
inc(Temp,sizeof(Count));
266
Info:=PPointer(Temp)^;
267
inc(Temp,sizeof(Info));
269
for I:=0 to Count-1 do
270
fpc_Copy_internal(Src+(I*size),Dest+(I*size),Info);
276
Temp:=PByte(TypeInfo);
281
temp:=aligntoptr(temp);
283
Result:=plongint(temp)^;
289
Count:=PLongint(Temp)^;
290
inc(Temp,sizeof(longint));
292
{ Process elements with rtti }
295
Info:=PPointer(Temp)^;
296
inc(Temp,sizeof(Info));
297
Offset:=PLongint(Temp)^;
298
if Offset>expectedoffset then
299
move((Src+expectedoffset)^,(Dest+expectedoffset)^,Offset-expectedoffset);
300
inc(Temp,sizeof(longint));
301
copiedsize:=fpc_Copy_internal(Src+Offset,Dest+Offset,Info);
302
expectedoffset:=Offset+copiedsize;
304
{ elements remaining? }
305
if result>expectedoffset then
306
move((Src+expectedoffset)^,(Dest+expectedoffset)^,Result-expectedoffset);
310
fpc_dynarray_Incr_Ref(PPointer(Src)^);
311
fpc_dynarray_Decr_Ref(PPointer(Dest)^,typeinfo);
312
PPointer(Dest)^:=PPointer(Src)^;
316
Intf_Incr_Ref(PPointer(Src)^);
317
Intf_Decr_Ref(PPointer(Dest)^);
318
PPointer(Dest)^:=PPointer(Src)^;
322
VarCopyProc(pvardata(dest)^,pvardata(src)^);
323
result:=sizeof(tvardata);
329
procedure fpc_finalize_array(data,typeinfo : pointer;count,size : longint); [Public,Alias:'FPC_FINALIZEARRAY']; compilerproc;
333
for i:=0 to count-1 do
334
int_finalize(data+size*i,typeinfo);