Mac Local Procedure Parameters

From Free Pascal wiki
Logo OSX.png

This article applies to macOS only.

See also: Multiplatform Programming Guide

In procedure A, a reference to a local or global procedure C is to be passed as a parameter to a procedure B. Procedure B might be declared in another unit, unaware of possible type of callers. The body of B will in turn call procedure C. If procedure C is local, it can now access variables local to A, if global, it can't. Procedure B might also pass the parameter further, but is not allowed to store the parameter in a variable.

The procedure parameters can be implemented as a conceptual record with one procedure pointer and one local scope pointer.

When passing local procedures, the local scope pointer will point to the local variables, when passing a global procedure, the local scope pointer is set to nil.

The tricky problem is how B should call C. If the local scope pointer is nil, C should be called as a global procedure, if not nil it should be called as a local procedure, that is along with the local scope pointer.

By putting the local scope pointe last, the procedure calling code chunk can be the same for local and global calls. A runtime check checks whether the local scope pointer is not nil, and if so push it.

All three procedures A, B and C has to be declared in MacPas units for this to work, otherwise a compilation error should be risen.

In the future, for some register based calling conventions, if the local scope pointer is put in a register which otherwise would not be in use, the runtime check can be optimized away. (for PowerPC, if the local scope pointer happen to be allocated in one of r3 - r10)

Also, cdecl for local proc calls should not be allowed.