functions returning pionters to func - (nf)

rpw3 at fortune.UUCP rpw3 at fortune.UUCP
Sat Dec 17 19:05:44 AEST 1983


#R:azure:-243000:fortune:26900005:000:2673
fortune!rpw3    Dec 17 00:16:00 1983

Lo, I too have fought the mighty type-check and been victorious!
(Enough ancient grammer...)

The following code was the result of trying to declare a VARIABLE (as
opposed to the original submitter's ROUTINE) named "state", said
variable to hold the address of an array of routines, each of which
returns a value of the same type as "state" (i.e., a pointer to an
array of routines which...).

In case you haven't guessed, this is to build FAST state machines for
which the state and an input value maps directly to an action routine.
The application was, well, never mind... Each interrupt would process
all of the state transitions needed until no more work could be done.

After I had stumbled through all of the hassles mentioned previously,
I finally solved it using typedefs, but wasn't happy, since there seemed
something inelegant about that. The following program does it WITHOUT
typedefs (although the typedef version is easier to read, and was what
was used in production). Read carefully! The line that starts "struct..."
is actually declaring "state". (Ignore the missing initialization of "state")

Rob Warnock

UUCP:	{sri-unix,amd70,hpda,harpo,ihnp4,allegra}!fortune!rpw3
DDD:	(415)595-8444
USPS:	Fortune Systems Corp, 101 Twin Dolphins Drive, Redwood City, CA 94065

----------- sm.c --------------
extern char DR_flags;	/* argument to each state handler */

struct foo	{ struct foo (*(*dummy)())[];	} (*state)[];

/* called on each interrupt */
smachine()
{
	state = FIRSTSTATE;	/* defining FIRSTSTATE is hard, too */
	while (state)
	    state = (*((*state)[DR_flags].dummy))();  /* turn the crank */
}
---------------------------------

Here is the compiled code for a couple of machines. The typedef version
gives the same code, but the dummy struct member is avoided.

----------- smpdp10.mac ------------- (compiled from the original BLISS)
state::	block 1

_smachine::
	skipne	1,state
	popj 17,
	add	1,DR_flags##
	pushj	17,@(1)
	movem	1,state
	jrst	_smachine
----------- smvax.s -------------
.data
.comm	_state,4
.text
LL0:.align	1
.globl	_smachine
.set	L14,0x0
.data
.text
_smachine:.word	L14
jbr	L18
L2000001:cvtbl	_DR_flags,r0
ashl	$2,r0,r0
addl2	_state,r0
movl	(r0),r0
calls	$0,(r0)
movl	r0,_state
L18:tstl	_state
jneq	L2000001
ret
----------- sm68.s --------------
	.data
	.comm	state,4
	.text
	.globl	smachine
smachine:
	|.proc
	link	%a6,#-.F1
	movl	%a2,%sp@
	movl	#state,%a2
	jra	.L15
.L20001:
	movb	DR_flags,%d0
	extw	%d0
	extl	%d0
	asll	#2,%d0
	addl	%a2@,%d0
	movl	%d0,%a0
	movl	%a0@,%a0
	jsr	%a0@
	movl	%d0,%a2@
.L15:
	tstl	%a2@
	jne	.L20001
	movl	%a6@(-.F1),%a2
	unlk	%a6
	rts
.F1 = 4
	.S1 = 1024
	.data

----------end--------------------



More information about the Comp.unix mailing list