[comp.sys.mac.programmer] Dereferencing ProcPtr in LS Pascal

brianh@tasis.utas.oz.au@munnari.oz (Brian Harrold) (02/04/90)

To all Light Speed pascal gurus, I have a simple (?) question. 

   I have a procedure in which one of the parameters is of type
   ProcPtr (pointer to another procedure). Is there any way in 
   LS Pascal to dereference the pointer to the given procedure,
   and execute it ? 

Many thanx,

brian Harrold.
brianh@tasis.utas.oz 

siegel@endor.harvard.edu (Rich Siegel) (02/04/90)

In article <1268@diemen.cc.utas.oz> brianh@tasis.UUCP (Brian Harrold) writes:
>To all Light Speed pascal gurus, I have a simple (?) question. 
>
>   I have a procedure in which one of the parameters is of type
>   ProcPtr (pointer to another procedure). Is there any way in 
>   LS Pascal to dereference the pointer to the given procedure,
>   and execute it ? 

	Dereferencing a ProcPtr is a meaningless operation, since 
"procedure" isn't a data type. However, since we all know that a ProcPtr
points to a procedure's code, it is possible to call it:

PROCEDURE CallMyProcPtr(arg1 : Type1; arg2 : Type2;...argN : TypeN; addr : ProcPtr);
INLINE $205F { movea.l (a7)+, a0 }, $4E90 { JSR (a0) };

to call it:

	CallMyProcPtr(arg1, arg2,...argN, @MyProcedure);

R.


~~~~~~~~~~~~~~~
 Rich Siegel
 Staff Software Developer
 Symantec Corporation, Language Products Group
 Internet: siegel@endor.harvard.edu
 UUCP: ..harvard!endor!siegel

"When someone who makes four hundred and fifty dollars an hour wants to
tell you something for free, it's a good idea to listen."

~~~~~~~~~~~~~~~

philip@Kermit.Stanford.EDU (Philip Machanick) (02/05/90)

I attempted to mail the following, but the original author's address
didnn't work. Treat this with care; it needs to be checked.

In article <1268@diemen.cc.utas.oz> brian Harrold writes:
>
>    I have a procedure in which one of the parameters is of type
>    ProcPtr (pointer to another procedure). Is there any way in
>    LS Pascal to dereference the pointer to the given procedure,
>    and execute it ?
>
> brian Harrold.
> brianh@tasis.utas.oz

The solution is along the following lines:

procedure callProc(** parameters exactly as in proc ** ; theProc:
procPtr);
inline $205F $4ED0 ;  {check the syntax for inline in LS manual}

You will need a different version of callProc for each different
parameter list.

I don't have an assembler, a working example, the LS manual or a Mac
handy: this is from memory and a Motorola assembly language manual. You
should check this. The two hexadecimal numbers represent the following
assembly language:

     movea.l (SP)+, A0   ; pop the procptr into register A0
     jmp     (A0)        ; jump to the address pointed to by register A0

The effect of these instructions is to get you into the code pointed to
by the procPtr, with the stack set up as if you had done a direct call
to the proc (including having the return address in the right place).

You should check in the LS manual that I am right in assuming you can
trash the A0 register (see the section about interface to assembly
langauge). Also, it would be a good idea to run the above through an
assembler to check my hand-translation to hexadecimal.

To call the procPtr proc, do the following:

     callProc(** parameters exactly as in proc **, @proc)

Because of the way non-local variables are referenced, you should
declare the callProc procedure at the outermost level of a unit or of
the main program (i.e., it should not be a local procedure). I think
the compiler enforces this rule for generating the procPtr with the @
operation.

I hope this helps. If you can at all avoid it, don't do this kind of
thing. If you need to pass procedures around as data, use the
object-oriented features of the latest LS compiler instead. This kind
of hack defeats the purpose of a high-level language.

Philip Machanick
philip@pescadero.stanford.edu

beard@ux1.lbl.gov (Patrick C Beard) (02/05/90)

In article <1990Feb4.202759.16223@Neon.Stanford.EDU> philip@pescadero.stanford.edu writes:
#In article <1268@diemen.cc.utas.oz> brian Harrold writes:
#>
#>    I have a procedure in which one of the parameters is of type
#>    ProcPtr (pointer to another procedure). Is there any way in
#>    LS Pascal to dereference the pointer to the given procedure,
#>    and execute it ?
#>
#
#The solution is along the following lines:
#
#procedure callProc(** parameters exactly as in proc ** ; theProc:
#procPtr);
#inline $205F $4ED0 ;  {check the syntax for inline in LS manual}
#

By the way, MPW C++ will allow you to declare procedure pointer
types and call them directly by pointer, even when declared
as pascal!  THINK C doesn't let you do that...

For example:

typedef pascal OSErr (**GMProcHandle)(type1 arg1, type2 arg2, ...);

This type lets you call a code resource that has a funny calling convention.

	GMProcHandle myProcHandle = (GMProcHandle)GetResource(myId, 'ADgm');
	...
	HLock((Handle)myProcHandle);
	OSErr result = (**myProcHandle)(...);

Sure looks nice to me, don't have to do any of that funny inline code.


-------------------------------------------------------------------------------
-  Patrick Beard, Macintosh Programmer                        (beard@lbl.gov) -
-  Berkeley Systems, Inc.  ".......<dead air>.......Good day!" - Paul Harvey  -
-------------------------------------------------------------------------------