2
0
Эх сурвалжийг харах

* synchronized with trunk

git-svn-id: branches/wasm@48158 -
nickysn 4 жил өмнө
parent
commit
e0a1ce86fd

+ 1 - 0
.gitattributes

@@ -18684,6 +18684,7 @@ tests/webtbs/tw3827.pp svneol=native#text/plain
 tests/webtbs/tw3829.pp svneol=native#text/plain
 tests/webtbs/tw38295.pp svneol=native#text/pascal
 tests/webtbs/tw38299.pp svneol=native#text/pascal
+tests/webtbs/tw38306.pp -text svneol=native#text/pascal
 tests/webtbs/tw38309.pp svneol=native#text/pascal
 tests/webtbs/tw38310a.pp svneol=native#text/pascal
 tests/webtbs/tw38310b.pp svneol=native#text/pascal

+ 2 - 0
compiler/ogbase.pas

@@ -59,6 +59,8 @@ interface
          RELOC_RELATIVE_5,
          { PIC }
          RELOC_GOTPCREL,
+         RELOC_GOTPCRELX,
+         RELOC_REX_GOTPCRELX,
          RELOC_PLT32,
          RELOC_TLSGD,
          RELOC_TPOFF,

+ 6 - 0
compiler/x86_64/cpuelf.pas

@@ -88,6 +88,8 @@ implementation
     R_X86_64_TLSDESC_CALL = 35;
     R_X86_64_TLSDESC = 36;
     R_X86_64_IRELATIVE = 37;
+    R_X86_64_GOTPCRELX =41;
+    R_X86_64_REX_GOTPCRELX =42;
     R_X86_64_GNU_VTINHERIT = 250;    { GNU extension to record C++ vtable hierarchy }
     R_X86_64_GNU_VTENTRY = 251;      { GNU extension to record C++ vtable member usage }
 
@@ -169,6 +171,10 @@ implementation
           result:=R_X86_64_32S;
         RELOC_GOTPCREL :
           result:=R_X86_64_GOTPCREL;
+        RELOC_GOTPCRELX :
+          result:=R_X86_64_GOTPCRELX;
+        RELOC_REX_GOTPCRELX :
+          result:=R_X86_64_REX_GOTPCRELX;
         RELOC_PLT32 :
           result:=R_X86_64_PLT32;
         RELOC_TPOFF:

+ 34 - 6
packages/fcl-stl/src/gdeque.pp

@@ -30,7 +30,7 @@ type
     procedure SetValue(position:SizeUInt; value:T);inline;
     function GetValue(position:SizeUInt):T;inline;
     function GetMutable(position:SizeUInt):PT;inline;
-    procedure IncreaseCapacity();inline;
+    procedure IncreaseCapacity();
   public
     function Size():SizeUInt;inline;
     constructor Create();
@@ -142,7 +142,14 @@ begin
   GetMutable:=@FData[(FStart+position) mod FCapacity];
 end;
 
-procedure TDeque.IncreaseCapacity;inline;
+procedure TDeque.IncreaseCapacity;
+  function Min(const A,B: SizeUInt): SizeUInt; inline; //no need to drag in the entire Math unit ;-)
+  begin
+    if (A<B) then
+      Result:=A
+    else
+      Result:=B;
+  end;
 const
   // if size is small, multiply by 2;
   // if size bigger but <256M, inc by 1/8*size;
@@ -151,7 +158,7 @@ const
   cSizeBig = 256*1024*1024;
 var
   i,OldEnd,
-  DataSize:SizeUInt;
+  DataSize,CurLast,EmptyElems,Elems:SizeUInt;
 begin
   OldEnd:=FCapacity;
   DataSize:=FCapacity*SizeOf(T);
@@ -165,11 +172,32 @@ begin
     FCapacity:=FCapacity+FCapacity div 8
   else
     FCapacity:=FCapacity+FCapacity div 16;
-
   SetLength(FData, FCapacity);
   if (FStart>0) then
-    for i:=0 to FStart-1 do
-      FData[OldEnd+i]:=FData[i];
+  begin
+    if (FCapacity-OldEnd>=FStart) then //we have room to move all items in one go
+    begin
+      if IsManagedType(T) then
+        for i:=0 to FStart-1 do
+          FData[OldEnd+i]:=FData[i]
+      else
+        Move(FData[0], FData[OldEnd], FStart*SizeOf(T));
+    end
+    else
+    begin  //we have to move things around in chunks: we have more data in front of FStart than we have newly created unused elements
+      CurLast := OldEnd-1;
+      EmptyElems:=FCapacity-1-CurLast;
+      while (FStart>0) do
+      begin
+        Elems:=Min(EmptyElems, FStart);
+        for i:=0 to Elems-1 do
+          FData[CurLast+1+i]:=FData[i];
+        for i := 0 to FCapacity-Elems-1 do
+          FData[i]:=FData[Elems+i];
+        Dec(FStart, Elems);
+      end;
+    end;
+  end;
 end;
 
 procedure TDeque.Reserve(cap:SizeUInt);inline;

+ 26 - 13
packages/fpmkunit/src/fpmkunit.pp

@@ -2850,6 +2850,8 @@ function GetDefaultLibGCCDir(CPU : TCPU;OS: TOS; var ErrorMessage: string): stri
 var
   CrossPrefix: string;
   UseBinutilsPrefix: boolean;
+  SourceOS : TOS;
+  SourceCPU : TCPU;
 
   function Get4thWord(const AString: string): string;
   var p: pchar;
@@ -2916,24 +2918,35 @@ var
 begin
   result := '';
   ErrorMessage:='';
-  if (Defaults.SourceOS<>OS) then
+  if assigned(Defaults) then
+    begin
+      SourceOS:=Defaults.SourceOS;
+      SourceCPU:=Defaults.SourceCPU;
+    end
+  else
+    begin
+      SourceOS:=StringToOS({$I %FPCTARGETOS%});
+      SourceCPU:=StringToCPU({$I %FPCTARGETCPU%});
+    end;
+
+  if (SourceOS<>OS) then
     UseBinutilsPrefix:=true;
-  if (Defaults.SourceCPU<>CPU) then
+  if (SourceCPU<>CPU) then
     begin
       { we need to accept 32<->64 conversion }
       { expect for OpenBSD which does not allow this }
       if not(
-         ((Defaults.SourceCPU=aarch64) and (CPU=arm)) or
-         ((Defaults.SourceCPU=powerpc64) and (CPU=powerpc)) or
-         ((Defaults.SourceCPU=x86_64) and (CPU=i386)) or
-         ((Defaults.SourceCPU=riscv64) and (CPU=riscv32)) or
-         ((Defaults.SourceCPU=sparc64) and (CPU=sparc)) or
-         ((CPU=aarch64) and (Defaults.SourceCPU=arm)) or
-         ((CPU=powerpc64) and (Defaults.SourceCPU=powerpc)) or
-         ((CPU=x86_64) and (Defaults.SourceCPU=i386)) or
-         ((CPU=riscv64) and (Defaults.SourceCPU=riscv32)) or
-         ((CPU=sparc64) and (Defaults.SourceCPU=sparc))
-         ) or (Defaults.SourceOS=openbsd) then
+         ((SourceCPU=aarch64) and (CPU=arm)) or
+         ((SourceCPU=powerpc64) and (CPU=powerpc)) or
+         ((SourceCPU=x86_64) and (CPU=i386)) or
+         ((SourceCPU=riscv64) and (CPU=riscv32)) or
+         ((SourceCPU=sparc64) and (CPU=sparc)) or
+         ((CPU=aarch64) and (SourceCPU=arm)) or
+         ((CPU=powerpc64) and (SourceCPU=powerpc)) or
+         ((CPU=x86_64) and (SourceCPU=i386)) or
+         ((CPU=riscv64) and (SourceCPU=riscv32)) or
+         ((CPU=sparc64) and (SourceCPU=sparc))
+         ) or (SourceOS=openbsd) then
         UseBinutilsPrefix:=true; 
     end;
   if not UseBinutilsPrefix then

+ 39 - 0
tests/webtbs/tw38306.pp

@@ -0,0 +1,39 @@
+{ %OPT=-gh }
+{$mode objfpc}
+program gqueue_test;
+
+uses
+  gqueue;
+
+type
+  TIntQueue = specialize TQueue<Integer>;
+
+var
+  IntQueue: TIntQueue;
+  PushCnt: Integer;
+
+procedure Push2Pop1;
+var
+  i: Integer;
+begin
+  for i:= 0 to 1000000 do begin
+    IntQueue.Push(PushCnt);
+    inc(PushCnt);
+    IntQueue.Push(PushCnt);
+    inc(PushCnt);
+    IntQueue.Pop();
+  end;
+end;
+
+var
+  i: Integer;
+begin
+  try
+    IntQueue:= TIntQueue.Create;
+    Push2Pop1;
+    WriteLn('Ready');
+  finally
+    IntQueue.Free;
+  end;
+end.
+

+ 8 - 3
utils/pas2js/dist/rtl.js

@@ -739,15 +739,20 @@ var rtl = {
         delete this[id];
         old._Release(); // may fail
       }
-      this[id]=intf;
+      if(intf) {
+        this[id]=intf;
+      }
       return intf;
     },
     free: function(){
       //console.log('rtl.intfRefs.free...');
       for (var id in this){
         if (this.hasOwnProperty(id)){
-          //console.log('rtl.intfRefs.free: id='+id+' '+this[id].$name+' $o='+this[id].$o.$classname);
-          this[id]._Release();
+          var intf = this[id];
+          if (intf){
+            //console.log('rtl.intfRefs.free: id='+id+' '+intf.$name+' $o='+intf.$o.$classname);
+            intf._Release();
+          }
         }
       }
     }