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 _______________________________________________ fpc-devel maillist - fpc-devel@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-devel