From b58469a7bd20259b4e6ecbded940cc3a4593bee7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Van=20Canneyt?= <michael@freepascal.org>
Date: Mon, 17 Mar 2025 15:34:15 +0100
Subject: [PATCH] * Change pchar to dynamic array of ansichar

---
 compiler/aasmcnst.pas      | 30 ++++++++++------
 compiler/aasmtai.pas       | 72 ++++++++++++++++++++++++--------------
 compiler/aggas.pas         |  2 +-
 compiler/assemble.pas      |  2 +-
 compiler/entfile.pas       | 38 +++++++++++++++++++-
 compiler/globtype.pas      |  3 ++
 compiler/ogbase.pas        | 14 +++++++-
 compiler/wasm32/agwasa.pas | 12 +++++++
 8 files changed, 132 insertions(+), 41 deletions(-)

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