[fpc-devel] Local procedures as procedural parameter

DrDiettrich drdiettrich at compuserve.de
Fri Mar 18 11:21:04 CET 2005


Jonas Maebe wrote:

> > Couldn't the framepointer be last parameter in all modes ?
> 
> That would still require some ugly hacks inside the parameter passing
> code, because of the fact that on x86 the callee removes the parameters
> from the stack and not the caller (so you'd still need a check
> comparing that framepointer wil nil and not "pushing" it if it is nil).

>From the many contributions I got the following picture:

1) Local subroutines expect an framepointer, regardless of whether being
called from their enclosing subroutine, or from outside (as a callback).
This parameter must be passed, and possibly be removed from the stack,
in every call to, and return from, a local subroutine. All the technical
details are already specified, by the current handling of local calls to
local subroutines.

2) The compiler must check every call for local/global subroutines, in
order to supply or omit the framepointer. The only remarkable difference
are static/dynamic checks, where direct calls can be handled at compile
time, as is, whereas indirect calls would require a distinction at
runtime, based on the local/global kind of the actual callback
procedure.

So I wonder why there should be any problem, besides for the generation
of the code for the runtime checks?



3) Procedural parameters already come in two flavours, for global
subroutines and methods. The "of object" type has an additional Self
pointer field. It should not be hard to extend the base type with an
according Frame pointer field. This extension only is necessary for
parameters, not for variables of procedural type, because the compiler
should (already!) reject attempts to store references to local
subroutines in variables. Of course this change will break compatibility
with older binary code, such code must be recompiled with the new
compiler version.

Such a change may allow for really "smart" callbacks, where global or
local subroutines can be used for the same parameter, as well as methods
can be used without an explicit "of object" clause. In the latter case
distinct values must be used for the object (Self) pointer of methods,
to distinguish between methods with Self=nil, and ordinary subroutines
with no Self pointer at all.

The extension of the calling conventions may be a nasty task, but the
compiler already has implemented a bunch of calling conventions (cdecl,
pascal...) and modifications (method vs. ordinary subroutines, direct
vs. indirect calls). Only the very last case needs an update, so that
indirect calls have to be checked for local/global subroutines at
runtime. As mentioned above (3), additional dynamic support can
distinguish and handle global/local and subroutine/method variations
appropriately, as 4 distinct cases.

Since such "smart" callbacks require some amount of code, increasing the
size and runtime of the compiled code, it's up to the compiler writers
to add an compiler mode, option, or a flag, to enable/disable smart
callbacks and the according code production.


Did I miss anything?

What's your opinion on "smart" callbacks?
I mentioned this new construct based on my current observations with
comparison functions in sorting procedures. Wouldn't it be nice if one
could supply any kind of comparison function (local/global,
subroutine/method) to a single sorting procedure? Then the comparison
function could check flags and other values in their own runtime
environment, e.g. to distinguish between ascending/descending sort
order, in a thread-safe environment.

DoDi






More information about the fpc-devel mailing list