Hi all,

Seems like it that bug 18702 has nothing to do with my changes to the
stack-balancing code, and that nested function proc's never functioned
well on Windows.

The problem is that pop_parasize() is used to pop the stack-frame
pointer form the stack. But on 32-bit Windows, pop_parasize() has some
code to ensure that the funcret pointer is removed from the stack by the
caller. This is not applicable to the situation where only the
stack-frame pointer has to be popped from the stack.

A possible solution is attached, but I didn't commit it yet because I'm
nut sure if it is 'allowed' to use a 'target_info.system =
system_i386_win32' condition in ncgcal.pas. Other solutions could be to
add a parameter to pop_parasize or to add something like
pop_funcret_parasize().

Thoughts?

Joost.
Index: i386/n386cal.pas
===================================================================
--- i386/n386cal.pas	(revision 19881)
+++ i386/n386cal.pas	(working copy)
@@ -81,16 +81,6 @@
             exit;
           end;
 
-        { on win32, the caller is responsible for removing the funcret     }
-        { pointer from the stack, unlike on Linux. Don't know about        }
-        { elsewhere (except Darwin, handled above), but since the default  }
-        { was "callee removes funcret pointer from stack" until now, we'll }
-        { keep that default for everyone else (ncgcal decreases popsize by }
-        { sizeof(aint) in case of ret_in_param())                          }
-        if (target_info.system = system_i386_win32) and
-            paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
-          inc(pop_size,sizeof(aint));
-
         { better than an add on all processors }
         if pop_size=4 then
           begin
Index: ncgcal.pas
===================================================================
--- ncgcal.pas	(revision 19881)
+++ ncgcal.pas	(working copy)
@@ -875,6 +875,18 @@
                     (tf_safecall_exceptions in target_info.flags)) and
                paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
               dec(pop_size,sizeof(pint));
+
+            { on win32, the caller is responsible for removing the funcret     }
+            { pointer from the stack, unlike on Linux. Don't know about        }
+            { elsewhere (except Darwin, handled above), but since the default  }
+            { was "callee removes funcret pointer from stack" until now, we'll }
+            { keep that default for everyone else (ncgcal decreases popsize by }
+            { sizeof(aint) in case of ret_in_param())                          }
+            if (not paramanager.use_fixed_Stack) and
+               (target_info.system = system_i386_win32) and
+                paramanager.ret_in_param(procdefinition.returndef,procdefinition.proccalloption) then
+              inc(pop_size,sizeof(aint));
+
             { Remove parameters/alignment from the stack }
             pop_parasize(pop_size);
           end
_______________________________________________
fpc-devel maillist  -  [email protected]
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to