mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-28 16:01:48 +01:00
compiler:
- add TTagHashSet class descendant of THashSet with an ability to has also a LongWord value together with key - change TAsmData.ConstPools[] to be an indexed property to properly initialize ConstPool class, remove pool initialization from all other units - add ansistring constants to pool together with their encoding to distinct the same text constants with different codepage + test git-svn-id: trunk@19261 -
This commit is contained in:
parent
8ce243eafd
commit
4cf5e36ce7
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -9949,6 +9949,7 @@ tests/test/tconstref4.pp svneol=native#text/pascal
|
|||||||
tests/test/tcpstr1.pp svneol=native#text/plain
|
tests/test/tcpstr1.pp svneol=native#text/plain
|
||||||
tests/test/tcpstr10.pp svneol=native#text/pascal
|
tests/test/tcpstr10.pp svneol=native#text/pascal
|
||||||
tests/test/tcpstr11.pp svneol=native#text/pascal
|
tests/test/tcpstr11.pp svneol=native#text/pascal
|
||||||
|
tests/test/tcpstr12.pp svneol=native#text/pascal
|
||||||
tests/test/tcpstr2.pp svneol=native#text/plain
|
tests/test/tcpstr2.pp svneol=native#text/plain
|
||||||
tests/test/tcpstr2a.pp svneol=native#text/plain
|
tests/test/tcpstr2a.pp svneol=native#text/plain
|
||||||
tests/test/tcpstr3.pp svneol=native#text/plain
|
tests/test/tcpstr3.pp svneol=native#text/plain
|
||||||
|
|||||||
@ -138,6 +138,8 @@ interface
|
|||||||
end;
|
end;
|
||||||
TAsmCFIClass=class of TAsmCFI;
|
TAsmCFIClass=class of TAsmCFI;
|
||||||
|
|
||||||
|
{ TAsmData }
|
||||||
|
|
||||||
TAsmData = class
|
TAsmData = class
|
||||||
private
|
private
|
||||||
{ Symbols }
|
{ Symbols }
|
||||||
@ -147,6 +149,8 @@ interface
|
|||||||
FNextLabelNr : array[TAsmLabeltype] of longint;
|
FNextLabelNr : array[TAsmLabeltype] of longint;
|
||||||
{ Call Frame Information for stack unwinding}
|
{ Call Frame Information for stack unwinding}
|
||||||
FAsmCFI : TAsmCFI;
|
FAsmCFI : TAsmCFI;
|
||||||
|
FConstPools : array[TConstPoolType] of THashSet;
|
||||||
|
function GetConstPools(APoolType: TConstPoolType): THashSet;
|
||||||
public
|
public
|
||||||
name,
|
name,
|
||||||
realname : string[80];
|
realname : string[80];
|
||||||
@ -156,8 +160,6 @@ interface
|
|||||||
CurrAsmList : TAsmList;
|
CurrAsmList : TAsmList;
|
||||||
WideInits : TLinkedList;
|
WideInits : TLinkedList;
|
||||||
ResStrInits : TLinkedList;
|
ResStrInits : TLinkedList;
|
||||||
{ hash tables for reusing constant storage }
|
|
||||||
ConstPools : array[TConstPoolType] of THashSet;
|
|
||||||
constructor create(const n:string);
|
constructor create(const n:string);
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
{ asmsymbol }
|
{ asmsymbol }
|
||||||
@ -176,6 +178,8 @@ interface
|
|||||||
procedure ResetAltSymbols;
|
procedure ResetAltSymbols;
|
||||||
property AsmSymbolDict:TFPHashObjectList read FAsmSymbolDict;
|
property AsmSymbolDict:TFPHashObjectList read FAsmSymbolDict;
|
||||||
property AsmCFI:TAsmCFI read FAsmCFI;
|
property AsmCFI:TAsmCFI read FAsmCFI;
|
||||||
|
{ hash tables for reusing constant storage }
|
||||||
|
property ConstPools[APoolType:TConstPoolType]: THashSet read GetConstPools;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TTCInitItem = class(TLinkedListItem)
|
TTCInitItem = class(TLinkedListItem)
|
||||||
@ -315,6 +319,17 @@ implementation
|
|||||||
TAsmData
|
TAsmData
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|
||||||
|
function TAsmData.GetConstPools(APoolType: TConstPoolType): THashSet;
|
||||||
|
begin
|
||||||
|
if FConstPools[APoolType] = nil then
|
||||||
|
case APoolType of
|
||||||
|
sp_ansistr: FConstPools[APoolType] := TTagHashSet.Create(64, True, False);
|
||||||
|
else
|
||||||
|
FConstPools[APoolType] := THashSet.Create(64, True, False);
|
||||||
|
end;
|
||||||
|
Result := FConstPools[APoolType];
|
||||||
|
end;
|
||||||
|
|
||||||
constructor TAsmData.create(const n:string);
|
constructor TAsmData.create(const n:string);
|
||||||
var
|
var
|
||||||
alt : TAsmLabelType;
|
alt : TAsmLabelType;
|
||||||
@ -376,7 +391,7 @@ implementation
|
|||||||
memasmlists.stop;
|
memasmlists.stop;
|
||||||
{$endif}
|
{$endif}
|
||||||
for hp := low(TConstPoolType) to high(TConstPoolType) do
|
for hp := low(TConstPoolType) to high(TConstPoolType) do
|
||||||
ConstPools[hp].Free;
|
FConstPools[hp].Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -479,13 +479,16 @@ type
|
|||||||
THashSet = class(TObject)
|
THashSet = class(TObject)
|
||||||
private
|
private
|
||||||
FCount: LongWord;
|
FCount: LongWord;
|
||||||
FBucketCount: LongWord;
|
|
||||||
FBucket: PPHashSetItem;
|
|
||||||
FOwnsObjects: Boolean;
|
FOwnsObjects: Boolean;
|
||||||
FOwnsKeys: Boolean;
|
FOwnsKeys: Boolean;
|
||||||
function Lookup(Key: Pointer; KeyLen: Integer; var Found: Boolean;
|
function Lookup(Key: Pointer; KeyLen: Integer; var Found: Boolean;
|
||||||
CanCreate: Boolean): PHashSetItem;
|
CanCreate: Boolean): PHashSetItem;
|
||||||
procedure Resize(NewCapacity: LongWord);
|
procedure Resize(NewCapacity: LongWord);
|
||||||
|
protected
|
||||||
|
FBucket: PPHashSetItem;
|
||||||
|
FBucketCount: LongWord;
|
||||||
|
class procedure FreeItem(item:PHashSetItem); virtual;
|
||||||
|
class function SizeOfItem: Integer; virtual;
|
||||||
public
|
public
|
||||||
constructor Create(InitSize: Integer; OwnKeys, OwnObjects: Boolean);
|
constructor Create(InitSize: Integer; OwnKeys, OwnObjects: Boolean);
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -502,7 +505,40 @@ type
|
|||||||
{ removes an entry, returns False if entry wasn't there }
|
{ removes an entry, returns False if entry wasn't there }
|
||||||
function Remove(Entry: PHashSetItem): Boolean;
|
function Remove(Entry: PHashSetItem): Boolean;
|
||||||
property Count: LongWord read FCount;
|
property Count: LongWord read FCount;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{******************************************************************
|
||||||
|
TTagHasSet
|
||||||
|
*******************************************************************}
|
||||||
|
PPTagHashSetItem = ^PTagHashSetItem;
|
||||||
|
PTagHashSetItem = ^TTagHashSetItem;
|
||||||
|
TTagHashSetItem = record
|
||||||
|
Next: PTagHashSetItem;
|
||||||
|
Key: Pointer;
|
||||||
|
KeyLength: Integer;
|
||||||
|
HashValue: LongWord;
|
||||||
|
Data: TObject;
|
||||||
|
Tag: LongWord;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TTagHashSet = class(THashSet)
|
||||||
|
private
|
||||||
|
function Lookup(Key: Pointer; KeyLen: Integer; Tag: LongWord; var Found: Boolean;
|
||||||
|
CanCreate: Boolean): PTagHashSetItem;
|
||||||
|
protected
|
||||||
|
class procedure FreeItem(item:PHashSetItem); override;
|
||||||
|
class function SizeOfItem: Integer; override;
|
||||||
|
public
|
||||||
|
{ finds an entry by key }
|
||||||
|
function Find(Key: Pointer; KeyLen: Integer; Tag: LongWord): PTagHashSetItem; reintroduce;
|
||||||
|
{ finds an entry, creates one if not exists }
|
||||||
|
function FindOrAdd(Key: Pointer; KeyLen: Integer; Tag: LongWord;
|
||||||
|
var Found: Boolean): PTagHashSetItem; reintroduce;
|
||||||
|
{ finds an entry, creates one if not exists }
|
||||||
|
function FindOrAdd(Key: Pointer; KeyLen: Integer; Tag: LongWord): PTagHashSetItem; reintroduce;
|
||||||
|
{ returns Data by given Key }
|
||||||
|
function Get(Key: Pointer; KeyLen: Integer; Tag: LongWord): TObject; reintroduce;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{******************************************************************
|
{******************************************************************
|
||||||
@ -536,6 +572,7 @@ type
|
|||||||
|
|
||||||
function FPHash(const s:shortstring):LongWord;
|
function FPHash(const s:shortstring):LongWord;
|
||||||
function FPHash(P: PChar; Len: Integer): LongWord;
|
function FPHash(P: PChar; Len: Integer): LongWord;
|
||||||
|
function FPHash(P: PChar; Len: Integer; Tag: LongWord): LongWord;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -1118,6 +1155,21 @@ end;
|
|||||||
{$pop}
|
{$pop}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function FPHash(P: PChar; Len: Integer; Tag: LongWord): LongWord;
|
||||||
|
Var
|
||||||
|
pmax : pchar;
|
||||||
|
begin
|
||||||
|
{$push}
|
||||||
|
{$q-,r-}
|
||||||
|
result:=Tag;
|
||||||
|
pmax:=p+len;
|
||||||
|
while (p<pmax) do
|
||||||
|
begin
|
||||||
|
result:=LongWord(LongInt(result shl 5) - LongInt(result)) xor LongWord(P^);
|
||||||
|
inc(p);
|
||||||
|
end;
|
||||||
|
{$pop}
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TFPHashList.RaiseIndexError(Index : Integer);
|
procedure TFPHashList.RaiseIndexError(Index : Integer);
|
||||||
begin
|
begin
|
||||||
@ -2641,7 +2693,7 @@ end;
|
|||||||
item^.Data.Free;
|
item^.Data.Free;
|
||||||
if FOwnsKeys then
|
if FOwnsKeys then
|
||||||
FreeMem(item^.Key);
|
FreeMem(item^.Key);
|
||||||
Dispose(item);
|
FreeItem(item);
|
||||||
item := next;
|
item := next;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -2735,7 +2787,7 @@ end;
|
|||||||
i: Integer;
|
i: Integer;
|
||||||
e, n: PHashSetItem;
|
e, n: PHashSetItem;
|
||||||
begin
|
begin
|
||||||
p := AllocMem(NewCapacity * sizeof(PHashSetItem));
|
p := AllocMem(NewCapacity * SizeOfItem);
|
||||||
for i := 0 to FBucketCount-1 do
|
for i := 0 to FBucketCount-1 do
|
||||||
begin
|
begin
|
||||||
e := FBucket[i];
|
e := FBucket[i];
|
||||||
@ -2753,6 +2805,15 @@ end;
|
|||||||
FBucket := p;
|
FBucket := p;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
class procedure THashSet.FreeItem(item: PHashSetItem);
|
||||||
|
begin
|
||||||
|
Dispose(item);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function THashSet.SizeOfItem: Integer;
|
||||||
|
begin
|
||||||
|
Result := SizeOf(THashSetItem);
|
||||||
|
end;
|
||||||
|
|
||||||
function THashSet.Remove(Entry: PHashSetItem): Boolean;
|
function THashSet.Remove(Entry: PHashSetItem): Boolean;
|
||||||
var
|
var
|
||||||
@ -2768,7 +2829,7 @@ end;
|
|||||||
Entry^.Data.Free;
|
Entry^.Data.Free;
|
||||||
if FOwnsKeys then
|
if FOwnsKeys then
|
||||||
FreeMem(Entry^.Key);
|
FreeMem(Entry^.Key);
|
||||||
Dispose(Entry);
|
FreeItem(Entry);
|
||||||
Dec(FCount);
|
Dec(FCount);
|
||||||
Result := True;
|
Result := True;
|
||||||
Exit;
|
Exit;
|
||||||
@ -2779,6 +2840,96 @@ end;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{****************************************************************************
|
||||||
|
ttaghashset
|
||||||
|
****************************************************************************}
|
||||||
|
|
||||||
|
function TTagHashSet.Lookup(Key: Pointer; KeyLen: Integer;
|
||||||
|
Tag: LongWord; var Found: Boolean; CanCreate: Boolean): PTagHashSetItem;
|
||||||
|
var
|
||||||
|
Entry: PPTagHashSetItem;
|
||||||
|
h: LongWord;
|
||||||
|
begin
|
||||||
|
h := FPHash(Key, KeyLen, Tag);
|
||||||
|
Entry := @PPTagHashSetItem(FBucket)[h mod FBucketCount];
|
||||||
|
while Assigned(Entry^) and
|
||||||
|
not ((Entry^^.HashValue = h) and (Entry^^.KeyLength = KeyLen) and
|
||||||
|
(Entry^^.Tag = Tag) and (CompareByte(Entry^^.Key^, Key^, KeyLen) = 0)) do
|
||||||
|
Entry := @Entry^^.Next;
|
||||||
|
Found := Assigned(Entry^);
|
||||||
|
if Found or (not CanCreate) then
|
||||||
|
begin
|
||||||
|
Result := Entry^;
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
if FCount > FBucketCount then { arbitrary limit, probably too high }
|
||||||
|
begin
|
||||||
|
{ rehash and repeat search }
|
||||||
|
Resize(FBucketCount * 2);
|
||||||
|
Result := Lookup(Key, KeyLen, Tag, Found, CanCreate);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
New(Result);
|
||||||
|
if FOwnsKeys then
|
||||||
|
begin
|
||||||
|
GetMem(Result^.Key, KeyLen);
|
||||||
|
Move(Key^, Result^.Key^, KeyLen);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
Result^.Key := Key;
|
||||||
|
Result^.KeyLength := KeyLen;
|
||||||
|
Result^.HashValue := h;
|
||||||
|
Result^.Tag := Tag;
|
||||||
|
Result^.Data := nil;
|
||||||
|
Result^.Next := nil;
|
||||||
|
Inc(FCount);
|
||||||
|
Entry^ := Result;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
class procedure TTagHashSet.FreeItem(item: PHashSetItem);
|
||||||
|
begin
|
||||||
|
Dispose(PTagHashSetItem(item));
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TTagHashSet.SizeOfItem: Integer;
|
||||||
|
begin
|
||||||
|
Result := SizeOf(TTagHashSetItem);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTagHashSet.Find(Key: Pointer; KeyLen: Integer; Tag: LongWord): PTagHashSetItem;
|
||||||
|
var
|
||||||
|
Dummy: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Lookup(Key, KeyLen, Tag, Dummy, False);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTagHashSet.FindOrAdd(Key: Pointer; KeyLen: Integer; Tag: LongWord;
|
||||||
|
var Found: Boolean): PTagHashSetItem;
|
||||||
|
begin
|
||||||
|
Result := Lookup(Key, KeyLen, Tag, Found, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTagHashSet.FindOrAdd(Key: Pointer; KeyLen: Integer; Tag: LongWord): PTagHashSetItem;
|
||||||
|
var
|
||||||
|
Dummy: Boolean;
|
||||||
|
begin
|
||||||
|
Result := Lookup(Key, KeyLen, Tag, Dummy, True);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TTagHashSet.Get(Key: Pointer; KeyLen: Integer; Tag: LongWord): TObject;
|
||||||
|
var
|
||||||
|
e: PTagHashSetItem;
|
||||||
|
Dummy: Boolean;
|
||||||
|
begin
|
||||||
|
e := Lookup(Key, KeyLen, Tag, Dummy, False);
|
||||||
|
if Assigned(e) then
|
||||||
|
Result := e^.Data
|
||||||
|
else
|
||||||
|
Result := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
tbitset
|
tbitset
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|||||||
@ -139,9 +139,6 @@ implementation
|
|||||||
{ const already used ? }
|
{ const already used ? }
|
||||||
if not assigned(lab_real) then
|
if not assigned(lab_real) then
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[sp_floats] = nil then
|
|
||||||
current_asmdata.ConstPools[sp_floats] := THashSet.Create(64, True, False);
|
|
||||||
|
|
||||||
{ there may be gap between record fields, zero it out }
|
{ there may be gap between record fields, zero it out }
|
||||||
fillchar(key,sizeof(key),0);
|
fillchar(key,sizeof(key),0);
|
||||||
key.value:=value_real;
|
key.value:=value_real;
|
||||||
@ -255,11 +252,10 @@ implementation
|
|||||||
|
|
||||||
procedure tcgstringconstnode.pass_generate_code;
|
procedure tcgstringconstnode.pass_generate_code;
|
||||||
var
|
var
|
||||||
lastlabel : tasmlabel;
|
lastlabel: tasmlabel;
|
||||||
pc : pchar;
|
pc: pchar;
|
||||||
l: longint;
|
l: longint;
|
||||||
href: treference;
|
href: treference;
|
||||||
pooltype: TConstPoolType;
|
|
||||||
pool: THashSet;
|
pool: THashSet;
|
||||||
entry: PHashSetItem;
|
entry: PHashSetItem;
|
||||||
|
|
||||||
@ -283,13 +279,13 @@ implementation
|
|||||||
{ const already used ? }
|
{ const already used ? }
|
||||||
if not assigned(lab_str) then
|
if not assigned(lab_str) then
|
||||||
begin
|
begin
|
||||||
pooltype := PoolMap[cst_type];
|
pool := current_asmdata.ConstPools[PoolMap[cst_type]];
|
||||||
if current_asmdata.ConstPools[pooltype] = nil then
|
|
||||||
current_asmdata.ConstPools[pooltype] := THashSet.Create(64, True, False);
|
|
||||||
pool := current_asmdata.ConstPools[pooltype];
|
|
||||||
|
|
||||||
if cst_type in [cst_widestring, cst_unicodestring] then
|
if cst_type in [cst_widestring, cst_unicodestring] then
|
||||||
entry := pool.FindOrAdd(pcompilerwidestring(value_str)^.data, len*cwidechartype.size)
|
entry := pool.FindOrAdd(pcompilerwidestring(value_str)^.data, len*cwidechartype.size)
|
||||||
|
else
|
||||||
|
if cst_type = cst_ansistring then
|
||||||
|
entry := PHashSetItem(TTagHashSet(pool).FindOrAdd(value_str, len, tstringdef(resultdef).encoding))
|
||||||
else
|
else
|
||||||
entry := pool.FindOrAdd(value_str, len);
|
entry := pool.FindOrAdd(value_str, len);
|
||||||
|
|
||||||
@ -415,8 +411,6 @@ implementation
|
|||||||
{ const already used ? }
|
{ const already used ? }
|
||||||
if not assigned(lab_set) then
|
if not assigned(lab_set) then
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[sp_varsets] = nil then
|
|
||||||
current_asmdata.ConstPools[sp_varsets] := THashSet.Create(64, True, False);
|
|
||||||
entry := current_asmdata.ConstPools[sp_varsets].FindOrAdd(value_set, 32);
|
entry := current_asmdata.ConstPools[sp_varsets].FindOrAdd(value_set, 32);
|
||||||
|
|
||||||
lab_set := TAsmLabel(entry^.Data); // is it needed anymore?
|
lab_set := TAsmLabel(entry^.Data); // is it needed anymore?
|
||||||
|
|||||||
@ -114,8 +114,6 @@ implementation
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[sp_objcclassnamerefs]=nil then
|
|
||||||
current_asmdata.ConstPools[sp_objcclassnamerefs]:=THashSet.Create(64, True, False);
|
|
||||||
pool:=current_asmdata.ConstPools[sp_objcclassnamerefs];
|
pool:=current_asmdata.ConstPools[sp_objcclassnamerefs];
|
||||||
entry:=pool.FindOrAdd(@tobjectdef(left.resultdef).objextname^[1],length(tobjectdef(left.resultdef).objextname^));
|
entry:=pool.FindOrAdd(@tobjectdef(left.resultdef).objextname^[1],length(tobjectdef(left.resultdef).objextname^));
|
||||||
if (target_info.system in systems_objc_nfabi) then
|
if (target_info.system in systems_objc_nfabi) then
|
||||||
|
|||||||
@ -58,8 +58,6 @@ procedure tcgobjcselectornode.pass_generate_code;
|
|||||||
entry : PHashSetItem;
|
entry : PHashSetItem;
|
||||||
name : pshortstring;
|
name : pshortstring;
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[sp_varnamerefs]=nil then
|
|
||||||
current_asmdata.ConstPools[sp_varnamerefs]:=THashSet.Create(64, True, False);
|
|
||||||
pool:=current_asmdata.ConstPools[sp_varnamerefs];
|
pool:=current_asmdata.ConstPools[sp_varnamerefs];
|
||||||
|
|
||||||
case left.nodetype of
|
case left.nodetype of
|
||||||
|
|||||||
@ -133,9 +133,6 @@ function objcaddprotocolentry(const p: shortstring; ref: TAsmSymbol): Boolean;
|
|||||||
var
|
var
|
||||||
item : PHashSetItem;
|
item : PHashSetItem;
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[sp_objcprotocolrefs]=nil then
|
|
||||||
current_asmdata.ConstPools[sp_objcprotocolrefs]:=THashSet.Create(64, True, False);
|
|
||||||
|
|
||||||
item:=current_asmdata.constpools[sp_objcprotocolrefs].FindOrAdd(@p[1], length(p));
|
item:=current_asmdata.constpools[sp_objcprotocolrefs].FindOrAdd(@p[1], length(p));
|
||||||
Result:=(item^.Data=nil);
|
Result:=(item^.Data=nil);
|
||||||
if Result then
|
if Result then
|
||||||
@ -153,8 +150,6 @@ function objcreatestringpoolentryintern(p: pchar; len: longint; pooltype: tconst
|
|||||||
pc : pchar;
|
pc : pchar;
|
||||||
pool : THashSet;
|
pool : THashSet;
|
||||||
begin
|
begin
|
||||||
if current_asmdata.ConstPools[pooltype]=nil then
|
|
||||||
current_asmdata.ConstPools[pooltype]:=THashSet.Create(64, True, False);
|
|
||||||
pool := current_asmdata.constpools[pooltype];
|
pool := current_asmdata.constpools[pooltype];
|
||||||
|
|
||||||
entry:=pool.FindOrAdd(p,len);
|
entry:=pool.FindOrAdd(p,len);
|
||||||
|
|||||||
18
tests/test/tcpstr12.pp
Normal file
18
tests/test/tcpstr12.pp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
program tcpstr12;
|
||||||
|
|
||||||
|
// check that 'test' constants assigned to ansistring variables have different codepage
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
type
|
||||||
|
cp866 = type AnsiString(866);
|
||||||
|
var
|
||||||
|
A: cp866;
|
||||||
|
B: AnsiString;
|
||||||
|
begin
|
||||||
|
B := 'test';
|
||||||
|
// if StringCodePage(B) <> DefaultSystemCodePage then
|
||||||
|
// halt(1);
|
||||||
|
A := 'test';
|
||||||
|
if StringCodePage(A) <> 866 then
|
||||||
|
halt(2);
|
||||||
|
end.
|
||||||
Loading…
Reference in New Issue
Block a user