mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-13 02:29:36 +02:00

http://svn.freepascal.org/svn/fpc/branches/unicodestring ........ r11665 | florian | 2008-08-30 13:30:17 +0200 (Sat, 30 Aug 2008) | 1 line * continued to work on unicodestring type support ........ r11666 | florian | 2008-08-30 19:02:26 +0200 (Sat, 30 Aug 2008) | 2 lines * expectloc for wide/ansi/unicode strings is LOC_CONSTANT or LOC_REGISTER now ........ r11667 | florian | 2008-08-30 20:42:37 +0200 (Sat, 30 Aug 2008) | 1 line * more unicodestring stuff fixed, test results on win32 are already good ........ r11670 | florian | 2008-08-30 23:21:48 +0200 (Sat, 30 Aug 2008) | 2 lines * first fixes for unix bootstrapping ........ r11683 | ivost | 2008-09-01 12:46:39 +0200 (Mon, 01 Sep 2008) | 2 lines * fixed 64bit bug in iconvenc.pas ........ r11689 | florian | 2008-09-01 23:12:34 +0200 (Mon, 01 Sep 2008) | 1 line * fixed several errors when building on unix ........ r11694 | florian | 2008-09-03 20:32:43 +0200 (Wed, 03 Sep 2008) | 1 line * fixed unix compilation ........ r11695 | florian | 2008-09-03 21:01:04 +0200 (Wed, 03 Sep 2008) | 1 line * bootstrapping fix ........ r11696 | florian | 2008-09-03 21:07:18 +0200 (Wed, 03 Sep 2008) | 1 line * more bootstrapping fixed ........ r11698 | florian | 2008-09-03 22:47:54 +0200 (Wed, 03 Sep 2008) | 1 line + two missing compiler procs exported ........ r11701 | florian | 2008-09-04 16:42:34 +0200 (Thu, 04 Sep 2008) | 2 lines + lazarus project for the linux rtl ........ r11702 | florian | 2008-09-04 16:43:27 +0200 (Thu, 04 Sep 2008) | 2 lines + set unicode string procedures ........ r11707 | florian | 2008-09-04 23:23:02 +0200 (Thu, 04 Sep 2008) | 2 lines * fixed several type casting stuff ........ r11712 | florian | 2008-09-05 22:46:03 +0200 (Fri, 05 Sep 2008) | 1 line * fixed unicodestring compilation on windows after recent unix changes ........ r11713 | florian | 2008-09-05 23:35:12 +0200 (Fri, 05 Sep 2008) | 1 line + UnicodeString support for Variants ........ r11715 | florian | 2008-09-06 20:59:54 +0200 (Sat, 06 Sep 2008) | 1 line * patch by Martin Schreiber for UnicodeString streaming ........ r11716 | florian | 2008-09-06 22:22:55 +0200 (Sat, 06 Sep 2008) | 2 lines * fixed test ........ r11717 | florian | 2008-09-07 10:25:51 +0200 (Sun, 07 Sep 2008) | 1 line * fixed typo when converting tunicodestring to punicodechar ........ r11718 | florian | 2008-09-07 11:29:52 +0200 (Sun, 07 Sep 2008) | 3 lines * fixed writing of UnicodeString properties * moved some helper routines to unicode headers ........ r11734 | florian | 2008-09-09 22:38:55 +0200 (Tue, 09 Sep 2008) | 1 line * fixed bootstrapping ........ r11735 | florian | 2008-09-10 11:25:28 +0200 (Wed, 10 Sep 2008) | 2 lines * first fixes for persisten unicodestrings ........ r11736 | florian | 2008-09-10 14:31:00 +0200 (Wed, 10 Sep 2008) | 3 lines Initialized merge tracking via "svnmerge" with revisions "1-11663" from http://svn.freepascal.org/svn/fpc/trunk ........ r11737 | florian | 2008-09-10 21:06:57 +0200 (Wed, 10 Sep 2008) | 3 lines * fixed unicodestring <-> variant handling * fixed unicodestring property reading ........ git-svn-id: trunk@11739 -
378 lines
9.7 KiB
PHP
378 lines
9.7 KiB
PHP
{
|
|
This file is part of the Free Pascal run time library.
|
|
Copyright (c) 1999-2000 by Michael Van Canneyt
|
|
member of the Free Pascal development team
|
|
|
|
See the file COPYING.FPC, included in this distribution,
|
|
for details about the copyright.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
**********************************************************************}
|
|
|
|
{ Run-Time type information routines }
|
|
|
|
{ The RTTI is implemented through a series of constants : }
|
|
|
|
Const
|
|
tkUnknown = 0;
|
|
tkInteger = 1;
|
|
tkChar = 2;
|
|
tkEnumeration = 3;
|
|
tkFloat = 4;
|
|
tkSet = 5;
|
|
tkMethod = 6;
|
|
tkSString = 7;
|
|
tkString = tkSString;
|
|
tkLString = 8;
|
|
tkAString = 9;
|
|
tkWString = 10;
|
|
tkVariant = 11;
|
|
tkArray = 12;
|
|
tkRecord = 13;
|
|
tkInterface = 14;
|
|
tkClass = 15;
|
|
tkObject = 16;
|
|
tkWChar = 17;
|
|
tkBool = 18;
|
|
tkInt64 = 19;
|
|
tkQWord = 20;
|
|
tkDynArray = 21;
|
|
tkInterfaceCorba = 22;
|
|
tkProcVar = 23;
|
|
tkUString = 24;
|
|
|
|
|
|
type
|
|
TRTTIProc=procedure(Data,TypeInfo:Pointer);
|
|
|
|
{ if you modify this procedure, fpc_copy must be probably modified as well }
|
|
procedure RecordRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
|
|
{
|
|
A record is designed as follows :
|
|
1 : tkrecord
|
|
2 : Length of name string (n);
|
|
3 : name string;
|
|
3+n : record size;
|
|
7+n : number of elements (N)
|
|
11+n : N times : Pointer to type info
|
|
Offset in record
|
|
}
|
|
var
|
|
Temp : pbyte;
|
|
namelen : byte;
|
|
count,
|
|
offset,
|
|
i : longint;
|
|
info : pointer;
|
|
begin
|
|
Temp:=PByte(TypeInfo);
|
|
inc(Temp);
|
|
{ Skip Name }
|
|
namelen:=Temp^;
|
|
inc(temp,namelen+1);
|
|
temp:=aligntoptr(temp);
|
|
{ Skip size }
|
|
inc(Temp,4);
|
|
{ Element count }
|
|
Count:=PLongint(Temp)^;
|
|
inc(Temp,sizeof(Count));
|
|
{ Process elements }
|
|
for i:=1 to count Do
|
|
begin
|
|
Info:=PPointer(Temp)^;
|
|
inc(Temp,sizeof(Info));
|
|
Offset:=PLongint(Temp)^;
|
|
inc(Temp,sizeof(Offset));
|
|
rttiproc (Data+Offset,Info);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ if you modify this procedure, fpc_copy must be probably modified as well }
|
|
procedure ArrayRTTI(Data,TypeInfo:Pointer;rttiproc:TRTTIProc);
|
|
{
|
|
An array is designed as follows :
|
|
1 : tkArray;
|
|
2 : length of name string (n);
|
|
3 : NAme string
|
|
3+n : Element Size
|
|
7+n : Number of elements
|
|
11+n : Pointer to type of elements
|
|
}
|
|
var
|
|
Temp : pbyte;
|
|
namelen : byte;
|
|
count,
|
|
size,
|
|
i : SizeInt;
|
|
info : pointer;
|
|
begin
|
|
Temp:=PByte(TypeInfo);
|
|
inc(Temp);
|
|
{ Skip Name }
|
|
namelen:=Temp^;
|
|
inc(temp,namelen+1);
|
|
temp:=aligntoptr(temp);
|
|
{ Element size }
|
|
size:=PSizeInt(Temp)^;
|
|
inc(Temp,sizeof(Size));
|
|
{ Element count }
|
|
Count:=PSizeInt(Temp)^;
|
|
inc(Temp,sizeof(Count));
|
|
Info:=PPointer(Temp)^;
|
|
inc(Temp,sizeof(Info));
|
|
{ Process elements }
|
|
for I:=0 to Count-1 do
|
|
rttiproc(Data+(I*size),Info);
|
|
end;
|
|
|
|
|
|
Procedure fpc_Initialize (Data,TypeInfo : pointer);[Public,Alias : 'FPC_INITIALIZE']; compilerproc;
|
|
begin
|
|
case PByte(TypeInfo)^ of
|
|
tkAstring,tkWstring,tkUString,tkInterface,tkDynArray:
|
|
PPchar(Data)^:=Nil;
|
|
tkArray:
|
|
arrayrtti(data,typeinfo,@int_initialize);
|
|
tkObject,
|
|
tkRecord:
|
|
recordrtti(data,typeinfo,@int_initialize);
|
|
tkVariant:
|
|
variant_init(PVarData(Data)^);
|
|
end;
|
|
end;
|
|
|
|
|
|
Procedure fpc_finalize (Data,TypeInfo: Pointer);[Public,Alias : 'FPC_FINALIZE']; compilerproc;
|
|
begin
|
|
case PByte(TypeInfo)^ of
|
|
tkAstring :
|
|
begin
|
|
fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
|
|
PPointer(Data)^:=nil;
|
|
end;
|
|
{$ifndef VER2_2}
|
|
tkUstring :
|
|
begin
|
|
fpc_UnicodeStr_Decr_Ref(PPointer(Data)^);
|
|
PPointer(Data)^:=nil;
|
|
end;
|
|
{$endif VER2_2}
|
|
{$ifdef WINDOWS}
|
|
tkWstring :
|
|
begin
|
|
fpc_WideStr_Decr_Ref(PPointer(Data)^);
|
|
PPointer(Data)^:=nil;
|
|
end;
|
|
{$endif WINDOWS}
|
|
tkArray :
|
|
arrayrtti(data,typeinfo,@int_finalize);
|
|
tkObject,
|
|
tkRecord:
|
|
recordrtti(data,typeinfo,@int_finalize);
|
|
tkInterface:
|
|
begin
|
|
Intf_Decr_Ref(PPointer(Data)^);
|
|
PPointer(Data)^:=nil;
|
|
end;
|
|
tkDynArray:
|
|
fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
|
|
tkVariant:
|
|
variant_clear(PVarData(Data)^);
|
|
end;
|
|
end;
|
|
|
|
|
|
Procedure fpc_Addref (Data,TypeInfo : Pointer); [Public,alias : 'FPC_ADDREF']; compilerproc;
|
|
begin
|
|
case PByte(TypeInfo)^ of
|
|
tkAstring :
|
|
fpc_AnsiStr_Incr_Ref(PPointer(Data)^);
|
|
{$ifdef WINDOWS}
|
|
tkWstring :
|
|
fpc_WideStr_Incr_Ref(PPointer(Data)^);
|
|
{$endif WINDOWS}
|
|
{$ifndef VER2_2}
|
|
tkUstring :
|
|
fpc_UnicodeStr_Incr_Ref(PPointer(Data)^);
|
|
{$endif VER2_2}
|
|
tkArray :
|
|
arrayrtti(data,typeinfo,@int_addref);
|
|
tkobject,
|
|
tkrecord :
|
|
recordrtti(data,typeinfo,@int_addref);
|
|
tkDynArray:
|
|
fpc_dynarray_incr_ref(PPointer(Data)^);
|
|
tkInterface:
|
|
Intf_Incr_Ref(PPointer(Data)^);
|
|
tkVariant:
|
|
variant_addref(pvardata(Data)^);
|
|
end;
|
|
end;
|
|
|
|
|
|
{ alias for internal use }
|
|
{ we use another name else the compiler gets puzzled because of the wrong forward def }
|
|
procedure fpc_systemDecRef (Data, TypeInfo : Pointer);[external name 'FPC_DECREF'];
|
|
|
|
Procedure fpc_DecRef (Data, TypeInfo : Pointer);[Public,alias : 'FPC_DECREF']; compilerproc;
|
|
begin
|
|
case PByte(TypeInfo)^ of
|
|
{ see AddRef for comment about below construct (JM) }
|
|
tkAstring:
|
|
fpc_AnsiStr_Decr_Ref(PPointer(Data)^);
|
|
{$ifdef WINDOWS}
|
|
tkWstring:
|
|
fpc_WideStr_Decr_Ref(PPointer(Data)^);
|
|
{$endif WINDOWS}
|
|
{$ifndef VER2_2}
|
|
tkUString:
|
|
fpc_UnicodeStr_Decr_Ref(PPointer(Data)^);
|
|
{$endif VER2_2}
|
|
tkArray:
|
|
arrayrtti(data,typeinfo,@fpc_systemDecRef);
|
|
tkobject,
|
|
tkrecord:
|
|
recordrtti(data,typeinfo,@fpc_systemDecRef);
|
|
tkDynArray:
|
|
fpc_dynarray_decr_ref(PPointer(Data)^,TypeInfo);
|
|
tkInterface:
|
|
Intf_Decr_Ref(PPointer(Data)^);
|
|
tkVariant:
|
|
variant_clear(pvardata(data)^);
|
|
end;
|
|
end;
|
|
|
|
{ define alias for internal use in the system unit }
|
|
Function fpc_Copy_internal (Src, Dest, TypeInfo : Pointer) : SizeInt;[external name 'FPC_COPY'];
|
|
|
|
Function fpc_Copy (Src, Dest, TypeInfo : Pointer) : SizeInt;[Public,alias : 'FPC_COPY']; compilerproc;
|
|
var
|
|
Temp : pbyte;
|
|
namelen : byte;
|
|
copiedsize,
|
|
expectedoffset,
|
|
count,
|
|
offset,
|
|
size,
|
|
i : SizeInt;
|
|
info : pointer;
|
|
begin
|
|
result:=sizeof(pointer);
|
|
case PByte(TypeInfo)^ of
|
|
tkAstring:
|
|
begin
|
|
fpc_AnsiStr_Incr_Ref(PPointer(Src)^);
|
|
fpc_AnsiStr_Decr_Ref(PPointer(Dest)^);
|
|
PPointer(Dest)^:=PPointer(Src)^;
|
|
end;
|
|
{$ifdef WINDOWS}
|
|
tkWstring:
|
|
fpc_WideStr_Assign(PPointer(Dest)^,PPointer(Src)^);
|
|
{$endif WINDOWS}
|
|
{$ifndef VER2_2}
|
|
tkUstring:
|
|
fpc_UnicodeStr_Assign(PPointer(Dest)^,PPointer(Src)^);
|
|
{$endif VER2_2}
|
|
tkArray:
|
|
begin
|
|
Temp:=PByte(TypeInfo);
|
|
inc(Temp);
|
|
{ Skip Name }
|
|
namelen:=Temp^;
|
|
inc(temp,namelen+1);
|
|
temp:=aligntoptr(temp);
|
|
|
|
{ Element size }
|
|
size:=PSizeInt(Temp)^;
|
|
inc(Temp,sizeof(Size));
|
|
|
|
{ Element count }
|
|
Count:=PSizeInt(Temp)^;
|
|
inc(Temp,sizeof(Count));
|
|
Info:=PPointer(Temp)^;
|
|
inc(Temp,sizeof(Info));
|
|
{ Process elements }
|
|
for I:=0 to Count-1 do
|
|
fpc_Copy_internal(Src+(I*size),Dest+(I*size),Info);
|
|
Result:=size*count;
|
|
end;
|
|
tkobject,
|
|
tkrecord:
|
|
begin
|
|
Temp:=PByte(TypeInfo);
|
|
inc(Temp);
|
|
{ Skip Name }
|
|
namelen:=Temp^;
|
|
inc(temp,namelen+1);
|
|
temp:=aligntoptr(temp);
|
|
|
|
Result:=plongint(temp)^;
|
|
|
|
{ Skip size }
|
|
inc(Temp,4);
|
|
|
|
{ Element count }
|
|
Count:=PLongint(Temp)^;
|
|
inc(Temp,sizeof(longint));
|
|
expectedoffset:=0;
|
|
{ Process elements with rtti }
|
|
for i:=1 to count Do
|
|
begin
|
|
Info:=PPointer(Temp)^;
|
|
inc(Temp,sizeof(Info));
|
|
Offset:=PLongint(Temp)^;
|
|
if Offset>expectedoffset then
|
|
move((Src+expectedoffset)^,(Dest+expectedoffset)^,Offset-expectedoffset);
|
|
inc(Temp,sizeof(longint));
|
|
copiedsize:=fpc_Copy_internal(Src+Offset,Dest+Offset,Info);
|
|
expectedoffset:=Offset+copiedsize;
|
|
end;
|
|
{ elements remaining? }
|
|
if result>expectedoffset then
|
|
move((Src+expectedoffset)^,(Dest+expectedoffset)^,Result-expectedoffset);
|
|
end;
|
|
tkDynArray:
|
|
begin
|
|
fpc_dynarray_Incr_Ref(PPointer(Src)^);
|
|
fpc_dynarray_Decr_Ref(PPointer(Dest)^,typeinfo);
|
|
PPointer(Dest)^:=PPointer(Src)^;
|
|
end;
|
|
tkInterface:
|
|
begin
|
|
Intf_Incr_Ref(PPointer(Src)^);
|
|
Intf_Decr_Ref(PPointer(Dest)^);
|
|
PPointer(Dest)^:=PPointer(Src)^;
|
|
end;
|
|
tkVariant:
|
|
begin
|
|
VarCopyProc(pvardata(dest)^,pvardata(src)^);
|
|
result:=sizeof(tvardata);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
|
|
{ For internal use by the compiler, because otherwise $x- can cause trouble. }
|
|
{ Generally disabling extended syntax checking for all compilerprocs may }
|
|
{ have unintended side-effects }
|
|
procedure fpc_Copy_proc (Src, Dest, TypeInfo : Pointer);compilerproc; inline;
|
|
begin
|
|
fpc_copy_internal(src,dest,typeinfo);
|
|
end;
|
|
|
|
|
|
procedure fpc_finalize_array(data,typeinfo : pointer;count,size : SizeInt); [Public,Alias:'FPC_FINALIZEARRAY']; compilerproc;
|
|
var
|
|
i : SizeInt;
|
|
begin
|
|
if not(PByte(typeinfo)^ in [tkInteger,tkChar,tkEnumeration,tkFloat,tkSet,
|
|
tkMethod,tkSString,tkLString,tkWChar,tkBool,tkInt64,tkQWord]) then
|
|
for i:=0 to count-1 do
|
|
int_finalize(data+size*i,typeinfo);
|
|
end;
|
|
|