diff --git a/compiler/aasmcnst.pas b/compiler/aasmcnst.pas index c55dd9455f..3bd6351277 100644 --- a/compiler/aasmcnst.pas +++ b/compiler/aasmcnst.pas @@ -727,25 +727,30 @@ implementation end; procedure tai_aggregatetypedconst.add_to_string(strtai: tai_string; othertai: tai); + var + len1,len2,lent : Integer; + lother_string : tai_string absolute othertai; begin case othertai.typ of ait_string: begin - strtai.str:=reallocmem(strtai.str,strtai.len+tai_string(othertai).len+1); + // lengths without terminating 0 + len1:=length(strtai.str)-1; + len2:=length(lother_string.str)-1; + lent:=len1+len2; + SetLength(strtai.str,lent+1); { also copy null terminator } - move(tai_string(othertai).str[0],strtai.str[strtai.len],tai_string(othertai).len+1); - { the null terminator is not part of the string data } - strtai.len:=strtai.len+tai_string(othertai).len; + move(lother_string.str[0],strtai.str[len1+1],len2+1); end; ait_const: begin if tai_const(othertai).size<>1 then internalerror(2014070101); { it was already len+1 to hold the #0 -> realloc to len+2 } - strtai.str:=reallocmem(strtai.str,strtai.len+2); - strtai.str[strtai.len]:=ansichar(tai_const(othertai).value); - strtai.str[strtai.len+1]:=#0; - inc(strtai.len); + len1:=length(strtai.str); + SetLength(strtai.str,len1+1); + strtai.str[len1]:=ansichar(tai_const(othertai).value); + strtai.str[len1+1]:=#0; end; else internalerror(2014070102); @@ -826,6 +831,9 @@ implementation procedure tai_aggregatetypedconst.finish; + var + lString : tai_string; + len : integer; begin if fisstring then begin @@ -833,9 +841,9 @@ implementation data } if fvalues.count<>1 then internalerror(2014070105); - tai_simpletypedconst(fvalues[0]).fdef:= - carraydef.getreusable(cansichartype, - tai_string(tai_simpletypedconst(fvalues[0]).val).len); + lString:=tai_string(tai_simpletypedconst(fvalues[0]).val); + len:=length(lString.str)-1; + tai_simpletypedconst(fvalues[0]).fdef:=carraydef.getreusable(cansichartype,len); end; end; diff --git a/compiler/aasmtai.pas b/compiler/aasmtai.pas index 471c3d75aa..7aa8aba194 100644 --- a/compiler/aasmtai.pas +++ b/compiler/aasmtai.pas @@ -604,10 +604,11 @@ interface taiclassarray = array[taitype] of taiclass; { Generates an assembler string } + + { tai_string } + tai_string = class(tailineinfo) - str : pchar; - { extra len so the string can contain an \0 } - len : longint; + str : TAnsiCharDynArray; constructor Create(const _str : string); constructor Create(const _str : ansistring); constructor Create_pchar(_str : pchar;length : longint); @@ -615,6 +616,7 @@ interface constructor ppuload(t:taitype;ppufile:tcompilerppufile);override; procedure ppuwrite(ppufile:tcompilerppufile);override; function getcopy:tlinkedlistitem;override; + function len : integer; inline; end; { Generates a common label } @@ -2416,26 +2418,30 @@ implementation ****************************************************************************} constructor tai_string.Create(const _str : string); + var + lNewLen : Integer; begin inherited Create; typ:=ait_string; - len:=length(_str); - getmem(str,len+1); - if len>0 then - move(_str[1],str^,len); - str[len]:=#0; + lNewLen:=length(_str); + setlength(str,lNewLen+1); + if lNewLen>0 then + move(_str[1],str[0],lNewLen); + str[lNewLen]:=#0; end; constructor tai_string.Create(const _str: ansistring); + var + lNewLen : Integer; begin inherited Create; typ:=ait_string; - len:=length(_str); - getmem(str,len+1); - if len>0 then - move(_str[1],str^,len); - str[len]:=#0; + lNewLen:=length(_str); + setlength(str,lNewlen+1); + if lNewLen>0 then + move(_str[1],str[0],lNewLen); + str[lNewLen]:=#0; end; @@ -2443,47 +2449,61 @@ implementation begin inherited Create; typ:=ait_string; - str:=_str; - len:=length; + setlength(str,length+1); + move(_str^,str[0],length); + str[length]:=#0; end; - destructor tai_string.destroy; + destructor tai_string.Destroy; begin - if str<>nil then - freemem(str); inherited Destroy; end; constructor tai_string.ppuload(t:taitype;ppufile:tcompilerppufile); + var + lNewLen : integer; begin inherited ppuload(t,ppufile); - len:=ppufile.getlongint; - getmem(str,len+1); - ppufile.getdata(str^,len); - str[len]:=#0 + lNewLen:=ppufile.getlongint; + setlength(str,lNewLen+1); + ppufile.getdata(str); + str[lNewLen]:=#0; end; procedure tai_string.ppuwrite(ppufile:tcompilerppufile); + var + lWriteLen : integer; begin inherited ppuwrite(ppufile); - ppufile.putlongint(len); - ppufile.putdata(str^,len); + lWriteLen:=length(str); + ppufile.putlongint(lWriteLen); + ppufile.putdata(str[0],lWriteLen); end; function tai_string.getcopy : tlinkedlistitem; var p : tlinkedlistitem; + lWriteLen : integer; begin p:=inherited getcopy; - getmem(tai_string(p).str,len); - move(str^,tai_string(p).str^,len); + lWriteLen:=length(str); + setlength(tai_string(p).str,lWriteLen); + // move #0 at the end too. + move(str[0],tai_string(p).str[0],lWriteLen); getcopy:=p; end; + function tai_string.len: integer; + begin + Result:=Length(str); + if Result>0 then + Result:=Result-1; + end; + {**************************************************************************** TAI_LABEL diff --git a/compiler/aggas.pas b/compiler/aggas.pas index f0f8c53c05..add188d404 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -1303,7 +1303,7 @@ implementation writer.AsmWrite(#9'.ascii'#9'"'); pos:=20; end; - ch:=tai_string(hp).str[i-1]; + ch:=AnsiChar(tai_string(hp).str[i-1]); case ch of #0, {This can't be done by range, because a bug in FPC} #1..#31, diff --git a/compiler/assemble.pas b/compiler/assemble.pas index 028098e339..0e250ccdbf 100644 --- a/compiler/assemble.pas +++ b/compiler/assemble.pas @@ -2384,7 +2384,7 @@ Implementation end; end; ait_string : - ObjData.writebytes(Tai_string(hp).str^,Tai_string(hp).len); + ObjData.writebytes(Tai_string(hp).str,Tai_string(hp).len); ait_const : begin { Recalculate relative symbols, addresses of forward references diff --git a/compiler/entfile.pas b/compiler/entfile.pas index d05e1a3779..ceb23c7800 100644 --- a/compiler/entfile.pas +++ b/compiler/entfile.pas @@ -295,6 +295,8 @@ type function openstream(strm:TCStream):boolean; procedure reloadbuf; procedure readdata(out b;len:integer); + procedure readdata(const b : TByteDynArray); + procedure readdata(const b : TAnsiCharDynArray); procedure skipdata(len:integer); function readentry:byte; function EndOfEntry:boolean; {$ifdef USEINLINE}inline;{$endif} @@ -302,6 +304,8 @@ type function entryleft:longint; {$ifdef USEINLINE}inline;{$endif} procedure getdatabuf(out b;len:integer;out res:integer); procedure getdata(out b;len:integer); + procedure getdata(b : TByteDynArray); + procedure getdata(b : TAnsiCharDynArray); function getbyte:byte; function getword:word; function getdword:dword; @@ -736,6 +740,16 @@ begin inc(bufidx,len); end; +procedure tentryfile.readdata(const b: TByteDynArray); +begin + ReadData(B[0],Length(B)); +end; + +procedure tentryfile.readdata(const b: TAnsiCharDynArray); +begin + ReadData(B[0],Length(B)); +end; + procedure tentryfile.skipdata(len:integer); var @@ -800,7 +814,7 @@ begin end; -function tentryfile.endofentry:boolean; +function tentryfile.endofentry: boolean; begin {$ifdef generic_cpu} endofentry:=(entryidx=entry.size); @@ -843,6 +857,28 @@ begin inc(entryidx,len); end; +procedure tentryfile.getdata(b: TByteDynArray); +begin + if entryidx+Length(b)>entry.size then + begin + error:=true; + exit; + end; + readdata(b); + inc(entryidx,length(b)); +end; + +procedure tentryfile.getdata(b: TAnsiCharDynArray); +begin + if entryidx+Length(b)>entry.size then + begin + error:=true; + exit; + end; + readdata(b); + inc(entryidx,length(b)); +end; + function tentryfile.getbyte:byte; begin diff --git a/compiler/globtype.pas b/compiler/globtype.pas index 538460a01a..38e3539a6d 100644 --- a/compiler/globtype.pas +++ b/compiler/globtype.pas @@ -41,6 +41,9 @@ interface {$endif symansistr} PSymStr = ^TSymStr; + TByteDynArray = array of byte; + TAnsiCharDynArray = array of ansichar; + Int32 = Longint; { Integer type corresponding to pointer size } diff --git a/compiler/ogbase.pas b/compiler/ogbase.pas index ebe37ff8ee..b57aaa0ddf 100644 --- a/compiler/ogbase.pas +++ b/compiler/ogbase.pas @@ -458,6 +458,8 @@ interface procedure alloc(len:TObjSectionOfs); procedure allocalign(len:longint); procedure writebytes(const Data;len:TObjSectionOfs); + procedure writebytes(const Data : TByteDynArray;len:TObjSectionOfs); + procedure writebytes(const Data : TAnsiCharDynArray;len:TObjSectionOfs); procedure writeInt8(v: int8); procedure writeInt16LE(v: int16); procedure writeInt16BE(v: int16); @@ -1601,7 +1603,7 @@ implementation end; - function TObjData.FindSection(const aname:string):TObjSection; + function TObjData.Findsection(const aname:string):TObjSection; begin result:=TObjSection(FObjSectionList.Find(aname)); end; @@ -1724,6 +1726,16 @@ implementation CurrObjSec.write(Data,len); end; + procedure TObjData.writebytes(const Data: TByteDynArray; len: TObjSectionOfs); + begin + WriteBytes(Data[0],len); + end; + + procedure TObjData.writebytes(const Data: TAnsiCharDynArray; len: TObjSectionOfs); + begin + WriteBytes(Data[0],len); + end; + procedure TObjData.writeInt8(v: int8); begin diff --git a/compiler/wasm32/agwasa.pas b/compiler/wasm32/agwasa.pas index e1c039fab4..00d0d2bcb7 100644 --- a/compiler/wasm32/agwasa.pas +++ b/compiler/wasm32/agwasa.pas @@ -69,6 +69,8 @@ interface procedure WriteImports; procedure WriteOutPChar(p: pchar; ofs, len: integer); + procedure WriteOutPChar(p: TByteDynArray; ofs, len: integer); + procedure WriteOutPChar(p: TAnsicharDynArray; ofs, len: integer); procedure WriteConstString(lbl: tai_label; str: tai_string); procedure WriteConstants(p: TAsmList); public @@ -1025,6 +1027,16 @@ implementation end; end; + procedure TWasaTextAssembler.WriteOutPChar(p: TByteDynArray; ofs, len: integer); + begin + WriteOutPChar(PAnsiChar(p),ofs,len); + end; + + procedure TWasaTextAssembler.WriteOutPChar(p: TAnsicharDynArray; ofs, len: integer); + begin + WriteOutPChar(PAnsiChar(p),ofs,len); + end; + procedure TWasaTextAssembler.WriteConstString(lbl: tai_label; str: tai_string); var