瀏覽代碼

* reversed offset calculation for caller side so it works
correctly for interfaces

peter 22 年之前
父節點
當前提交
b26e3c444a
共有 3 個文件被更改,包括 56 次插入30 次删除
  1. 33 26
      compiler/i386/cpupara.pas
  2. 15 2
      compiler/ncal.pas
  3. 8 2
      compiler/nobj.pas

+ 33 - 26
compiler/i386/cpupara.pas

@@ -317,7 +317,15 @@ unit cpupara;
           and we save 6 register + 4 selectors }
         if po_interrupt in p.procoptions then
           inc(parasize,8+6*4+4*2);
-        { Assign fields }
+        { Offset is calculated like:
+           sub esp,12
+           mov [esp+8],para3
+           mov [esp+4],para2
+           mov [esp],para1
+           call function
+          That means the for pushes the para with the
+          highest offset (see para3) needs to be pushed first
+        }
         hp:=tparaitem(p.para.first);
         while assigned(hp) do
           begin
@@ -338,39 +346,34 @@ unit cpupara;
             hp.paraloc[side]:=paraloc;
             hp:=tparaitem(hp.next);
           end;
-        { Adapt offsets, for right-to-left calling we need to reverse the
-          offsets for the caller. For left-to-right calling we need to
-          reverse the offsets in the callee }
-        if (side=callerside) then
+        { Adapt offsets for left-to-right calling }
+        if p.proccalloption in pushleftright_pocalls then
           begin
-            if not(p.proccalloption in pushleftright_pocalls) then
+            hp:=tparaitem(p.para.first);
+            while assigned(hp) do
               begin
-                hp:=tparaitem(p.para.first);
-                while assigned(hp) do
-                  begin
-                    l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
-                    varalign:=used_align(size_2_align(l),paraalign,paraalign);
-                    l:=align(l,varalign);
-                    hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
-                    hp:=tparaitem(hp.next);
-                  end;
+                l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
+                varalign:=used_align(size_2_align(l),paraalign,paraalign);
+                l:=align(l,varalign);
+                hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
+                if side=calleeside then
+                  inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
+                hp:=tparaitem(hp.next);
               end;
           end
         else
           begin
-            hp:=tparaitem(p.para.first);
-            while assigned(hp) do
+            { Only need to adapt the callee side to include the
+              standard stackframe size }
+            if side=calleeside then
               begin
-                if (p.proccalloption in pushleftright_pocalls) then
+                hp:=tparaitem(p.para.first);
+                while assigned(hp) do
                   begin
-                    l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
-                    varalign:=used_align(size_2_align(l),paraalign,paraalign);
-                    l:=align(l,varalign);
-                    hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
+                    inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
+                    hp:=tparaitem(hp.next);
                   end;
-                inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
-                hp:=tparaitem(hp.next);
-              end;
+               end;
           end;
         { We need to return the size allocated }
         result:=parasize;
@@ -497,7 +500,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.44  2003-11-23 17:05:16  peter
+  Revision 1.45  2003-11-28 17:24:22  peter
+    * reversed offset calculation for caller side so it works
+      correctly for interfaces
+
+  Revision 1.44  2003/11/23 17:05:16  peter
     * register calling is left-right
     * parameter ordering
     * left-right calling inserts result parameter last

+ 15 - 2
compiler/ncal.pas

@@ -2363,9 +2363,18 @@ type
                       case hp.paraitem.paraloc[callerside].loc of
                         LOC_REFERENCE :
                           begin
+                            { Offset is calculated like:
+                               sub esp,12
+                               mov [esp+8],para3
+                               mov [esp+4],para2
+                               mov [esp],para1
+                               call function
+                              That means the for pushes the para with the
+                              highest offset (see para3) needs to be pushed first
+                            }
                             if (hpcurr.registers32>hp.registers32)
 {$ifdef x86}
-                               or (hpcurr.paraitem.paraloc[callerside].reference.offset<hp.paraitem.paraloc[callerside].reference.offset)
+                               or (hpcurr.paraitem.paraloc[callerside].reference.offset>hp.paraitem.paraloc[callerside].reference.offset)
 {$endif x86}
                                then
                               break;
@@ -2685,7 +2694,11 @@ begin
 end.
 {
   $Log$
-  Revision 1.208  2003-11-23 17:05:15  peter
+  Revision 1.209  2003-11-28 17:24:22  peter
+    * reversed offset calculation for caller side so it works
+      correctly for interfaces
+
+  Revision 1.208  2003/11/23 17:05:15  peter
     * register calling is left-right
     * parameter ordering
     * left-right calling inserts result parameter last

+ 8 - 2
compiler/nobj.pas

@@ -1354,7 +1354,9 @@ implementation
           cg.a_op_const_reg(exprasmlist,OP_SUB,locpara.size,ioffset,locpara.register);
         LOC_REFERENCE:
           begin
-             reference_reset_base(href,locpara.reference.index,locpara.reference.offset);
+             { offset in the wrapper needs to be adjusted for the stored
+               return address }
+             reference_reset_base(href,locpara.reference.index,locpara.reference.offset+POINTER_SIZE);
              cg.a_op_const_ref(exprasmlist,OP_SUB,locpara.size,ioffset,href);
           end
         else
@@ -1368,7 +1370,11 @@ initialization
 end.
 {
   $Log$
-  Revision 1.55  2003-10-30 16:23:13  peter
+  Revision 1.56  2003-11-28 17:24:22  peter
+    * reversed offset calculation for caller side so it works
+      correctly for interfaces
+
+  Revision 1.55  2003/10/30 16:23:13  peter
     * don't search for overloads in parents for constructors
 
   Revision 1.54  2003/10/29 19:48:50  peter