Ver código fonte

Merged revisions 11058-11059 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r11058 | florian | 2008-05-23 18:02:17 +0200 (Fr, 23 Mai 2008) | 2 lines

* take care of the maximum constant size when creating interface wrappers, resolves #10831
........
r11059 | florian | 2008-05-23 18:16:34 +0200 (Fr, 23 Mai 2008) | 2 lines

* test for previous commit
* fixed wrapper generation for bigger offsets as well
........

git-svn-id: branches/fixes_2_2@11060 -

florian 17 anos atrás
pai
commit
aa4c11be52
3 arquivos alterados com 78 adições e 1 exclusões
  1. 1 0
      .gitattributes
  2. 62 1
      compiler/arm/cgcpu.pas
  3. 15 0
      tests/webtbs/tw10831.pp

+ 1 - 0
.gitattributes

@@ -7971,6 +7971,7 @@ tests/webtbs/tw10800.pp svneol=native#text/plain
 tests/webtbs/tw1081.pp svneol=native#text/plain
 tests/webtbs/tw10815.pp svneol=native#text/plain
 tests/webtbs/tw10825.pp svneol=native#text/plain
+tests/webtbs/tw10831.pp svneol=native#text/plain
 tests/webtbs/tw10863.pp svneol=native#text/plain
 tests/webtbs/tw10890.pp svneol=native#text/plain
 tests/webtbs/tw10897.pp svneol=native#text/plain

+ 62 - 1
compiler/arm/cgcpu.pas

@@ -106,7 +106,7 @@ unit cgcpu;
         function handle_load_store(list:TAsmList;op: tasmop;oppostfix : toppostfix;reg:tregister;ref: treference):treference;
 
         procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
-
+        procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);
       private
         { clear out potential overflow bits from 8 or 16 bit operations  }
         { the upper 24/16 bits of a register after an operation          }
@@ -1880,6 +1880,59 @@ unit cgcpu;
       end;
 
 
+    procedure tcgarm.g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);
+      var
+        hsym : tsym;
+        href : treference;
+        paraloc : Pcgparalocation;
+        shift : byte;
+      begin
+        { calculate the parameter info for the procdef }
+        if not procdef.has_paraloc_info then
+          begin
+            procdef.requiredargarea:=paramanager.create_paraloc_info(procdef,callerside);
+            procdef.has_paraloc_info:=true;
+          end;
+        hsym:=tsym(procdef.parast.Find('self'));
+        if not(assigned(hsym) and
+          (hsym.typ=paravarsym)) then
+          internalerror(200305251);
+        paraloc:=tparavarsym(hsym).paraloc[callerside].location;
+        while paraloc<>nil do
+          with paraloc^ do
+            begin
+              case loc of
+                LOC_REGISTER:
+                  begin
+                    if is_shifter_const(ioffset,shift) then
+                      a_op_const_reg(list,OP_SUB,size,ioffset,register)
+                    else
+                      begin
+                        a_load_const_reg(list,OS_ADDR,ioffset,NR_R12);
+                        a_op_reg_reg(list,OP_SUB,size,NR_R12,register);
+                      end;
+                  end;
+                LOC_REFERENCE:
+                  begin
+                    { offset in the wrapper needs to be adjusted for the stored
+                      return address }
+                    reference_reset_base(href,reference.index,reference.offset+sizeof(aint));
+                    if is_shifter_const(ioffset,shift) then
+                      a_op_const_ref(list,OP_SUB,size,ioffset,href)
+                    else
+                      begin
+                        a_load_const_reg(list,OS_ADDR,ioffset,NR_R12);
+                        a_op_reg_ref(list,OP_SUB,size,NR_R12,href);
+                      end;
+                  end
+                else
+                  internalerror(200309189);
+              end;
+              paraloc:=next;
+            end;
+      end;
+
+
     procedure tcgarm.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);
 
       procedure loadvmttor12;
@@ -1926,6 +1979,10 @@ unit cgcpu;
         else
           list.concat(Tai_symbol.Createname(labelname,AT_FUNCTION,0));
 
+        { the wrapper might need aktlocaldata for the additional data to
+          load the constant }
+        current_procinfo:=cprocinfo.create(nil);
+
         { set param1 interface to self  }
         g_adjust_self_value(list,procdef,ioffset);
 
@@ -1938,6 +1995,10 @@ unit cgcpu;
         { case 0 }
         else
           list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(procdef.mangledname)));
+        list.concatlist(current_procinfo.aktlocaldata);
+
+        current_procinfo.Free;
+        current_procinfo:=nil;
 
         list.concat(Tai_symbol_end.Createname(labelname));
       end;

+ 15 - 0
tests/webtbs/tw10831.pp

@@ -0,0 +1,15 @@
+program test;
+
+type
+  TForm = class(TInterfacedObject)
+    a : array[0..1000000] of byte;
+  end;
+
+  TMyForm = class(TForm, IInterface)
+  end;
+
+var
+  i : IInterface;
+begin
+  i:=TMyForm.Create;
+end.