[comp.sys.mac.programmer] Executing a code segement from Lightspeed Pascal?

harrow@bagels.dec.com (Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) (10/05/88)

I've got  a  programming question (which will show my weakness in
Pascal... Oh well)

I'm trying to  use  the  HelpCompiler  that came over Usenet.  It
places help text and  a  CODE  resource into a program, which you
call with the following "C" code:

#include <MacTypes.h>

ShowHelp()
{
        Handle  rsrcH;
        ProcPtr pp;
        
        if (rsrcH = GetResource('CODE', 2000))
        {
                HLock(rsrcH);
                pp = (ProcPtr) *rsrcH;
                (*pp)();
                ReleaseResource(rsrcH);
        }
}


Now, I tried to convert this to Pascal (Lightspeed, of course) as
follows:

procedure ShowHelp;
  var
   rsrcH : Handle;
   pp : ProcPtr;

 begin
  if rsrcH = GetResource('code', 2000) then
   begin
    HLock(rsrcH);
    pp := @rsrcH;
    pp;         <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<<
    ReleaseResource(rsrcH);
   end;
 end;

but I can't figure out how  to  actually  EXECUTE the code, whose
entry point address should, I think, be  in pp.  (Some varients I
tried are shown above.)

I know that you have to be tricky in Pascal to do this, but what
am I missing?

Thanks,

Jeff Harrow

Work address:
ARPAnet:	HARROW%BAGELS.DEC@decwrl.ARPA
Usenet:		decwrl!bagels.dec.com!harrow        or
                {allegra,Shasta,decvax}!decwrl!dec-rhea!dec-bagels!harrow
Easynet:	BAGELS::HARROW
Telephone:	(508)486-5564
USPS:		Digital Equipment Corp.
		Mail stop: LKG2-2/Y10
		550 King St.
		Littleton, MA  01460

earleh@eleazar.dartmouth.edu (Earle R. Horton) (10/05/88)

In article <8810051239.AA09466@decwrl.dec.com> harrow@bagels.dec.com 
	(Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) writes:

>I'm trying to  use  the  HelpCompiler  that came over Usenet.  It
>places help text and  a  CODE  resource into a program, which you
>call with the following "C" code:
...
>Now, I tried to convert this to Pascal (Lightspeed, of course) as
>follows:
>
>procedure ShowHelp;
>  var
>   rsrcH : Handle;
>   pp : ProcPtr;
>
> begin
>  if rsrcH = GetResource('code', 2000) then
>   begin
>    HLock(rsrcH);
>    pp := @rsrcH;
>    pp;         <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<<

The data type ProcPtr technically points to an arbitrary type, I think
it is SignedByte in Pascal.  Therefore there is no way to call the
routine directly from Pascal, without using assembly language or
InLine assembly.

Something like the following should work:

PROCEDURE CallCodeResource(theProc: ProcPtr);
INLINE $205F,$4E90;
 {MOVE.L (A7)+,A0 JSR (A0) }

This InLine code pops the ProcPtr off the stack, then does a JSR to
it, putting the real return address on the stack.  You would use it by:

CallCodeResource(pp);

This, of course, assumes that LightSpeed Pascal allows InLine
declarations using the same syntax used by MPW Pascal.


Earle R. Horton. 23 Fletcher Circle, Hanover, NH 03755
(603) 643-4109
Sorry, no fancy stuff, since this program limits my .signature to three

oster@dewey.soe.berkeley.edu (David Phillip Oster) (10/06/88)

As others have pointed out:
1.) you can use inline code
2.) you can use an assembly language glue routine linked into your
program.

Now:
3.) you can use pascal itself. Pascal lets you write routines with
procedure valued parameters. Just call it with the argument:

procedure callpascal(procedure a(b:integer); b:integer);
  begin
    a(b);
  end;

now, suppose foo is a procedure pointer variable. if you
say:
  callpascal( appropriatecasttocircumventpascaltypechecking(foo), 22);
it will do the right thing.

You can play games by breaking the program up into multiple files and
declaring callpascal() differently where it is defined from where it is
used.

--- David Phillip Oster            --When you asked me to live in sin with you
Arpa: oster@dewey.soe.berkeley.edu --I didn't know you meant sloth.
Uucp: {uwvax,decvax,ihnp4}!ucbvax!oster%dewey.soe.berkeley.edu

iand@munnari.oz (Ian Robert Dobson) (10/06/88)

> 
> I know that you have to be tricky in Pascal to do this, but what
> am I missing?
>

Apple mentions in Inside Mac 1 that there is no way the Lisa Pascal
compiler can call a routine pointed to by a ProcPtr.  Probably the
same problem exists with LightSpeed Pascal.  Does anybody know a way
around this with INLINEs?
   Apart from that, your translation of C to Pascal is incorrect.
The C statement "if (rsrcH = GetResource('code',2000)" includes an
assignment, NOT a equality comparison.  This should be translated
as:
       rsrcH := GetResource('code',2000);
       if rsrcH <> nil then ....


Ian R. Dobson
University of Melbourne
munnari!iand
 

singer@endor.harvard.edu (Rich Siegel) (10/06/88)

In article <8810051239.AA09466@decwrl.dec.com> harrow@bagels.dec.com (Jeff Harrow, NMSG LKG2-2/Y10 DTN=226-5564) writes:
>I've got  a  programming question (which will show my weakness in
>Pascal... Oh well)
>
>
>Now, I tried to convert this to Pascal (Lightspeed, of course) as
>follows:
>
>procedure ShowHelp;
>  var
>   rsrcH : Handle;
>   pp : ProcPtr;
>
> begin
>  if rsrcH = GetResource('code', 2000) then
>   begin
>    HLock(rsrcH);
>    pp := @rsrcH;
>    pp;         <<<<<THIS, nor @PP, nor (@PP) works<<<<<<<<
>    ReleaseResource(rsrcH);
>   end;
> end;
>
>but I can't figure out how  to  actually  EXECUTE the code, whose
>entry point address should, I think, be  in pp.  (Some varients I
>tried are shown above.)

>I know that you have to be tricky in Pascal to do this, but what
>am I missing?

	Two things to do:

	First, if you're writing your code resource in C, the main routine
should be of type "pascal", as in

	pascal void main()

Second, to call a ProcPtr, you need the following inLine:

	PROCEDURE CallProc(p : ProcPtr);
	inline $205F, $4E90;

	which pops the last argument off the stack, and JSRs to it.

So...

	procedure ShowHelp;
	var 
		H : Handle;
		hState : SignedByte;
	
	begin
		H := GetResource('Code', 2000);
		if H <> NIL) then begin
			hState := HGetState(h);
			MoveHHi(h);
			HLock(h);
			CallProc(h^);
			HSetState(h, hState);
		end
	end;

The calls to HGetState and HSetState ensure that the resource is returned
to the same state of locked-ness when you're done with it, instead of
unconditionally unlocking it every time.

		--Rich

Rich Siegel
Staff Software Developer
THINK Technologies Division, Symantec Corp.
Internet: singer@endor.harvard.edu
UUCP: ..harvard!endor!singer
Phone: (617) 275-4800 x305

Any opinions stated in this article do not necessarily reflect the views
or policies of Symantec Corporation or its employees.