mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-11-04 10:39:40 +01:00 
			
		
		
		
	o based on a patch by Rika, resolves #39401:
* use Base64 (62=_, 63=$) encoded FNV hash (instead of CR-32) to shorted identifiers
    * renamed fpccrc to fpchash
    + test
			
			
This commit is contained in:
		
							parent
							
								
									bae50d80d2
								
							
						
					
					
						commit
						a4672fbd1c
					
				@ -265,7 +265,7 @@ interface
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
    uses
 | 
			
		||||
      verbose,fpccrc;
 | 
			
		||||
      verbose,fpchash;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    function create_smartlink_sections:boolean;inline;
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
{
 | 
			
		||||
    Copyright (c) 2000-2002 by Free Pascal Development Team
 | 
			
		||||
 | 
			
		||||
    Routines to compute CRC values
 | 
			
		||||
    Routines to compute hash values
 | 
			
		||||
 | 
			
		||||
    This program is free software; you can redistribute it and/or modify
 | 
			
		||||
    it under the terms of the GNU General Public License as published by
 | 
			
		||||
@ -19,7 +19,7 @@
 | 
			
		||||
 | 
			
		||||
 ****************************************************************************
 | 
			
		||||
}
 | 
			
		||||
Unit fpccrc;
 | 
			
		||||
Unit fpchash;
 | 
			
		||||
 | 
			
		||||
{$i fpcdefs.inc}
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,16 @@ Function UpdateCrc32(InitCrc:cardinal;const InBuf;InLen:integer):cardinal;
 | 
			
		||||
  The resulting string is guaranteed to be not longer than maxlen. }
 | 
			
		||||
function TrimStrCRC32(const s: ansistring; maxlen: longint): ansistring;
 | 
			
		||||
 | 
			
		||||
{ calculate string hash using FNV Hash:
 | 
			
		||||
  http://www.isthe.com/chongo/tech/comp/fnv/
 | 
			
		||||
}
 | 
			
		||||
function UpdateFnv64(const InitFnv: uint64; const InBuf; InLen: Integer): uint64;
 | 
			
		||||
 | 
			
		||||
type
 | 
			
		||||
  Base64OfUint64String = string[11];
 | 
			
		||||
 | 
			
		||||
function Base64Mangle(const x: uint64): Base64OfUint64String;
 | 
			
		||||
 | 
			
		||||
Implementation
 | 
			
		||||
 | 
			
		||||
{*****************************************************************************
 | 
			
		||||
@ -92,4 +102,58 @@ begin
 | 
			
		||||
   end;
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
{ calculate string hash using FNV Hash:
 | 
			
		||||
  http://www.isthe.com/chongo/tech/comp/fnv/
 | 
			
		||||
}
 | 
			
		||||
{$push} {$rangechecks off} {$overflowchecks off}
 | 
			
		||||
function UpdateFnv64(const InitFnv: uint64; const InBuf; InLen: Integer): uint64;
 | 
			
		||||
const
 | 
			
		||||
  M = uint64(1099511628211);
 | 
			
		||||
  { Compiler yells at you for overflows in constants, even with disabled range checks,
 | 
			
		||||
    so there are precalculated values for unrolled loop: M^2, M^3, M^4. }
 | 
			
		||||
  Mp2 = uint64(956575116354345);
 | 
			
		||||
  Mp3 = uint64(624165263380053675);
 | 
			
		||||
  Mp4 = uint64(11527715348014283921);
 | 
			
		||||
var
 | 
			
		||||
  pp: pByte;
 | 
			
		||||
begin
 | 
			
		||||
  result := InitFnv;
 | 
			
		||||
  pp := @InBuf;
 | 
			
		||||
  while InLen >= 4 do
 | 
			
		||||
   begin
 | 
			
		||||
     result := (result + pp[0]) * Mp4 + pp[1] * Mp3 + pp[2] * Mp2 + pp[3] * M;
 | 
			
		||||
     pp := pp + 4;
 | 
			
		||||
     InLen := InLen - 4;
 | 
			
		||||
   end;
 | 
			
		||||
  while InLen > 0 do
 | 
			
		||||
   begin
 | 
			
		||||
     result := (result + pp^) * M;
 | 
			
		||||
     pp := pp + 1;
 | 
			
		||||
     InLen := InLen - 1;
 | 
			
		||||
   end;
 | 
			
		||||
end;
 | 
			
		||||
{$pop}
 | 
			
		||||
 | 
			
		||||
const
 | 
			
		||||
  Base64Chars: array[0 .. 63] of char = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$';
 | 
			
		||||
 | 
			
		||||
function Base64Mangle(const x: uint64): Base64OfUint64String;
 | 
			
		||||
var
 | 
			
		||||
  b64chars: pChar;
 | 
			
		||||
begin
 | 
			
		||||
  b64chars := pChar(Base64Chars);
 | 
			
		||||
  result[0] := #11;
 | 
			
		||||
  result[1] := b64chars[x and $3f];
 | 
			
		||||
  result[2] := b64chars[uint32(x) shr 6 and $3f];
 | 
			
		||||
  result[3] := b64chars[uint32(x) shr 12 and $3f];
 | 
			
		||||
  result[4] := b64chars[uint32(x) shr 18 and $3f];
 | 
			
		||||
  result[5] := b64chars[uint32(x) shr 24 and $3f];
 | 
			
		||||
  result[6] := b64chars[x shr 30 and $3f];
 | 
			
		||||
  result[7] := b64chars[x shr 36 and $3f];
 | 
			
		||||
  result[8] := b64chars[x shr 42 and $3f];
 | 
			
		||||
  result[9] := b64chars[x shr 48 and $3f];
 | 
			
		||||
  result[10] := b64chars[x shr 54 and $3f];
 | 
			
		||||
  result[11] := b64chars[x shr 60];
 | 
			
		||||
end;
 | 
			
		||||
 | 
			
		||||
end.
 | 
			
		||||
@ -170,7 +170,7 @@ Implementation
 | 
			
		||||
{$ifdef hasUnix}
 | 
			
		||||
      baseunix,
 | 
			
		||||
{$endif hasUnix}
 | 
			
		||||
      cscript,globals,verbose,comphook,ppu,fpccrc,
 | 
			
		||||
      cscript,globals,verbose,comphook,ppu,fpchash,
 | 
			
		||||
      aasmbase,aasmcpu,
 | 
			
		||||
      ogmap;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -99,7 +99,7 @@ implementation
 | 
			
		||||
 | 
			
		||||
    uses
 | 
			
		||||
      cutils,cclasses,
 | 
			
		||||
      fpccrc,
 | 
			
		||||
      fpchash,
 | 
			
		||||
      globtype,globals,verbose,constexp,
 | 
			
		||||
      systems,fmodule,
 | 
			
		||||
      symsym,symtable,symcreat,
 | 
			
		||||
 | 
			
		||||
@ -73,7 +73,7 @@ interface
 | 
			
		||||
implementation
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  fpccrc;
 | 
			
		||||
  fpchash;
 | 
			
		||||
 | 
			
		||||
  { tpcpfile }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -63,7 +63,7 @@ implementation
 | 
			
		||||
 | 
			
		||||
uses
 | 
			
		||||
  { common }
 | 
			
		||||
  cutils,fpccrc,
 | 
			
		||||
  cutils,fpchash,
 | 
			
		||||
  { global }
 | 
			
		||||
  globals,tokens,verbose,finput,constexp,
 | 
			
		||||
  { symtable }
 | 
			
		||||
 | 
			
		||||
@ -175,7 +175,7 @@ implementation
 | 
			
		||||
{$ifdef Test_Double_checksum}
 | 
			
		||||
    comphook,
 | 
			
		||||
{$endif def Test_Double_checksum}
 | 
			
		||||
    fpccrc;
 | 
			
		||||
    fpchash;
 | 
			
		||||
 | 
			
		||||
{$ifdef Test_Double_checksum}
 | 
			
		||||
{$ifdef TEST_CRC_ERROR}
 | 
			
		||||
 | 
			
		||||
@ -1363,7 +1363,7 @@ implementation
 | 
			
		||||
      { other }
 | 
			
		||||
      aasmbase,
 | 
			
		||||
      gendef,
 | 
			
		||||
      fpccrc,
 | 
			
		||||
      fpchash,
 | 
			
		||||
      entfile
 | 
			
		||||
      ;
 | 
			
		||||
 | 
			
		||||
@ -1533,7 +1533,7 @@ implementation
 | 
			
		||||
      var
 | 
			
		||||
        s,
 | 
			
		||||
        prefix : TSymStr;
 | 
			
		||||
        crc : dword;
 | 
			
		||||
        hash : qword;
 | 
			
		||||
      begin
 | 
			
		||||
        prefix:='';
 | 
			
		||||
        if not assigned(st) then
 | 
			
		||||
@ -1555,9 +1555,9 @@ implementation
 | 
			
		||||
               prefix:=s;
 | 
			
		||||
             if length(prefix)>100 then
 | 
			
		||||
               begin
 | 
			
		||||
                 crc:=0;
 | 
			
		||||
                 crc:=UpdateCrc32(crc,prefix[1],length(prefix));
 | 
			
		||||
                 prefix:='$CRC'+hexstr(crc,8);
 | 
			
		||||
                 hash:=0;
 | 
			
		||||
                 hash:=UpdateFnv64(hash,prefix[1],length(prefix));
 | 
			
		||||
                 prefix:='$H'+Base64Mangle(hash);
 | 
			
		||||
               end;
 | 
			
		||||
             st:=st.defowner.owner;
 | 
			
		||||
           end;
 | 
			
		||||
@ -5454,7 +5454,7 @@ implementation
 | 
			
		||||
 | 
			
		||||
    function tabstractprocdef.mangledprocparanames(oldlen : longint) : string;
 | 
			
		||||
      var
 | 
			
		||||
        crc  : dword;
 | 
			
		||||
        hash  : qword;
 | 
			
		||||
        hp   : TParavarsym;
 | 
			
		||||
        hs   : TSymStr;
 | 
			
		||||
        newlen,
 | 
			
		||||
@ -5474,27 +5474,27 @@ implementation
 | 
			
		||||
        if not is_void(returndef) then
 | 
			
		||||
          result:=result+'$$'+returndef.mangledparaname;
 | 
			
		||||
        newlen:=length(result)+oldlen;
 | 
			
		||||
        { Replace with CRC if the parameter line is very long }
 | 
			
		||||
        { Replace with hash if the parameter line is very long }
 | 
			
		||||
        if (newlen-oldlen>12) and
 | 
			
		||||
           ((newlen>100) or (newlen-oldlen>64)) then
 | 
			
		||||
          begin
 | 
			
		||||
            crc:=0;
 | 
			
		||||
            hash:=0;
 | 
			
		||||
            for i:=0 to paras.count-1 do
 | 
			
		||||
              begin
 | 
			
		||||
                hp:=tparavarsym(paras[i]);
 | 
			
		||||
                if not(vo_is_hidden_para in hp.varoptions) then
 | 
			
		||||
                  begin
 | 
			
		||||
                    hs:=hp.vardef.mangledparaname;
 | 
			
		||||
                    crc:=UpdateCrc32(crc,hs[1],length(hs));
 | 
			
		||||
                    hash:=UpdateFnv64(hash,hs[1],length(hs));
 | 
			
		||||
                  end;
 | 
			
		||||
              end;
 | 
			
		||||
            if not is_void(returndef) then
 | 
			
		||||
              begin
 | 
			
		||||
                { add a little prefix so that x(integer; integer) is different from x(integer):integer }
 | 
			
		||||
                hs:='$$'+returndef.mangledparaname;
 | 
			
		||||
                crc:=UpdateCrc32(crc,hs[1],length(hs));
 | 
			
		||||
                hash:=UpdateFnv64(hash,hs[1],length(hs));
 | 
			
		||||
              end;
 | 
			
		||||
            result:='$crc'+hexstr(crc,8);
 | 
			
		||||
            result:='$h'+Base64Mangle(hash);
 | 
			
		||||
          end;
 | 
			
		||||
      end;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								tests/webtbs/tw39401.pp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								tests/webtbs/tw39401.pp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,27 @@
 | 
			
		||||
{ %norun }
 | 
			
		||||
{$mode objfpc}
 | 
			
		||||
type
 | 
			
		||||
	Collide29685295 = type uint32;
 | 
			
		||||
	Collide32060020 = type uint32;
 | 
			
		||||
 | 
			
		||||
	SomeType = class
 | 
			
		||||
	type
 | 
			
		||||
		SomeNestedType = class
 | 
			
		||||
		type
 | 
			
		||||
			YetAnotherNestedType = class
 | 
			
		||||
				class procedure Hello(arg: YetAnotherNestedType; arg2: Collide29685295); static;
 | 
			
		||||
				class procedure Hello(arg: YetAnotherNestedType; arg2: Collide32060020); static;
 | 
			
		||||
			end;
 | 
			
		||||
		end;
 | 
			
		||||
	end;
 | 
			
		||||
 | 
			
		||||
	class procedure SomeType.SomeNestedType.YetAnotherNestedType.Hello(arg: YetAnotherNestedType; arg2: Collide29685295);
 | 
			
		||||
	begin
 | 
			
		||||
	end;
 | 
			
		||||
 | 
			
		||||
	class procedure SomeType.SomeNestedType.YetAnotherNestedType.Hello(arg: YetAnotherNestedType; arg2: Collide32060020);
 | 
			
		||||
	begin
 | 
			
		||||
	end;
 | 
			
		||||
 | 
			
		||||
begin
 | 
			
		||||
end.
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user