home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
src
/
runtime
/
rcoexpr.r
< prev
next >
Wrap
Text File
|
2001-12-12
|
8KB
|
316 lines
/*
* File: rcoexpr.r -- co_init, co_chng
*/
#if COMPILER
static continuation coexpr_fnc; /* function to call after switching stacks */
#endif /* COMPILER */
/*
* co_init - use the contents of the refresh block to initialize the
* co-expression.
*/
void co_init(sblkp)
struct b_coexpr *sblkp;
{
#ifndef Coexpr
syserr("co_init() called, but co-expressions not implemented");
#else /* Coexpr */
register word *newsp;
register struct b_refresh *rblkp;
register dptr dp, dsp;
int frame_size;
word stack_strt;
int na, nl, nt, i;
/*
* Get pointer to refresh block.
*/
rblkp = (struct b_refresh *)BlkLoc(sblkp->freshblk);
#if COMPILER
na = rblkp->nargs; /* number of arguments */
nl = rblkp->nlocals; /* number of locals */
nt = rblkp->ntemps; /* number of temporaries */
/*
* The C stack must be aligned on the correct boundary. For up-growing
* stacks, the C stack starts after the initial procedure frame of
* the co-expression block. For down-growing stacks, the C stack starts
* at the last word of the co-expression block.
*/
#ifdef UpStack
frame_size = sizeof(struct p_frame) + sizeof(struct descrip) * (nl + na +
nt - 1) + rblkp->wrk_size;
stack_strt = (word)((char *)&sblkp->pf + frame_size + StackAlign*WordSize);
#else /* UpStack */
stack_strt = (word)((char *)sblkp + stksize - WordSize);
#endif /* UpStack */
sblkp->cstate[0] = stack_strt & ~(WordSize * StackAlign - 1);
sblkp->es_argp = &sblkp->pf.tend.d[nl + nt]; /* args follow temporaries */
#else /* COMPILER */
na = (rblkp->pfmkr).pf_nargs + 1; /* number of arguments */
nl = (int)rblkp->numlocals; /* number of locals */
/*
* The interpreter stack starts at word after co-expression stack block.
* C stack starts at end of stack region on machines with down-growing C
* stacks and somewhere in the middle of the region.
*
* The C stack is aligned on a doubleword boundary. For up-growing
* stacks, the C stack starts in the middle of the stack portion
* of the static block. For down-growing stacks, the C stack starts
* at the last word of the static block.
*/
newsp = (word *)((char *)sblkp + sizeof(struct b_coexpr));
#ifdef UpStack
sblkp->cstate[0] =
((word)((char *)sblkp + (stksize - sizeof(*sblkp))/2)
&~((word)WordSize*StackAlign-1));
#else /* UpStack */
sblkp->cstate[0] =
((word)((char *)sblkp + stksize - WordSize)
&~((word)WordSize*StackAlign-1));
#endif /* UpStack */
sblkp->es_argp = (dptr)newsp; /* args are first thing on stack */
#endif /* COMPILER */
/*
* Copy arguments onto new stack.
*/
dsp = sblkp->es_argp;
dp = rblkp->elems;
for (i = 1; i <= na; i++)
*dsp++ = *dp++;
/*
* Set up state variables and initialize procedure frame.
*/
#if COMPILER
sblkp->es_pfp = &sblkp->pf;
sblkp->es_tend = &sblkp->pf.tend;
sblkp->pf.old_pfp = NULL;
sblkp->pf.rslt = NULL;
sblkp->pf.succ_cont = NULL;
sblkp->pf.tend.previous = NULL;
sblkp->pf.tend.num = nl + na + nt;
sblkp->es_actstk = NULL;
#else /* COMPILER */
*((struct pf_marker *)dsp) = rblkp->pfmkr;
sblkp->es_pfp = (struct pf_marker *)dsp;
sblkp->es_tend = NULL;
dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
sblkp->es_ipc.opnd = rblkp->ep;
sblkp->es_gfp = 0;
sblkp->es_efp = 0;
sblkp->es_ilevel = 0;
#endif /* COMPILER */
sblkp->tvalloc = NULL;
/*
* Copy locals into the co-expression.
*/
#if COMPILER
dsp = sblkp->pf.tend.d;
#endif /* COMPILER */
for (i = 1; i <= nl; i++)
*dsp++ = *dp++;
#if COMPILER
/*
* Initialize temporary variables.
*/
for (i = 1; i <= nt; i++)
*dsp++ = nulldesc;
#else /* COMPILER */
/*
* Push two null descriptors on the stack.
*/
*dsp++ = nulldesc;
*dsp++ = nulldesc;
sblkp->es_sp = (word *)dsp - 1;
#endif /* COMPILER */
#endif /* Coexpr */
}
/*
* co_chng - high-level co-expression context switch.
*/
int co_chng(ncp, valloc, rsltloc, swtch_typ, first)
struct b_coexpr *ncp;
struct descrip *valloc; /* location of value being transmitted */
struct descrip *rsltloc;/* location to put result */
int swtch_typ; /* A_Coact, A_Coret, A_Cofail, or A_MTEvent */
int first;
{
#ifndef Coexpr
syserr("co_chng() called, but co-expressions not implemented");
#else /* Coexpr */
register struct b_coexpr *ccp;
static int coexp_act; /* used to pass signal across activations */
/* back to whomever activates, if they care */
ccp = (struct b_coexpr *)BlkLoc(k_current);
#if !COMPILER
#ifdef EventMon
switch(swtch_typ) {
/*
* A_MTEvent does not generate an event.
*/
case A_MTEvent:
break;
case A_Coact:
EVValX(ncp,E_Coact);
if (!is:null(curpstate->eventmask)) {
curpstate->parent->eventsource.dword = D_Coexpr;
BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
}
break;
case A_Coret:
EVValX(ncp,E_Coret);
if (!is:null(curpstate->eventmask)) {
curpstate->parent->eventsource.dword = D_Coexpr;
BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
}
break;
case A_Cofail:
EVValX(ncp,E_Cofail);
if (!is:null(curpstate->eventmask) && ncp->program == curpstate) {
curpstate->parent->eventsource.dword = D_Coexpr;
BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
}
break;
}
#endif /* EventMon */
#endif /* COMPILER */
/*
* Determine if we need to transmit a value.
*/
if (valloc != NULL) {
#if !COMPILER
/*
* Determine if we need to dereference the transmitted value.
*/
if (Var(*valloc))
retderef(valloc, (word *)glbl_argp, sp);
#endif /* COMPILER */
if (ncp->tvalloc != NULL)
*ncp->tvalloc = *valloc;
}
ncp->tvalloc = NULL;
ccp->tvalloc = rsltloc;
/*
* Save state of current co-expression.
*/
ccp->es_pfp = pfp;
ccp->es_argp = glbl_argp;
ccp->es_tend = tend;
#if !COMPILER
ccp->es_efp = efp;
ccp->es_gfp = gfp;
ccp->es_ipc = ipc;
ccp->es_sp = sp;
ccp->es_ilevel = ilevel;
#endif /* COMPILER */
#if COMPILER
if (line_info) {
ccp->file_name = file_name;
ccp->line_num = line_num;
file_name = ncp->file_name;
line_num = ncp->line_num;
}
#endif /* COMPILER */
#if COMPILER
if (debug_info)
#endif /* COMPILER */
if (k_trace)
#ifdef EventMon
if (swtch_typ != A_MTEvent)
#endif /* EventMon */
cotrace(ccp, ncp, swtch_typ, valloc);
/*
* Establish state for new co-expression.
*/
pfp = ncp->es_pfp;
tend = ncp->es_tend;
#if !COMPILER
efp = ncp->es_efp;
gfp = ncp->es_gfp;
ipc = ncp->es_ipc;
sp = ncp->es_sp;
ilevel = (int)ncp->es_ilevel;
#endif /* COMPILER */
#if !COMPILER
#ifdef MultiThread
/*
* Enter the program state of the co-expression being activated
*/
ENTERPSTATE(ncp->program);
#endif /* MultiThread */
#endif /* COMPILER */
glbl_argp = ncp->es_argp;
BlkLoc(k_current) = (union block *)ncp;
#if COMPILER
coexpr_fnc = ncp->fnc;
#endif /* COMPILER */
#ifdef EventMon
/*
* From here on out, A_MTEvent looks like a A_Coact.
*/
if (swtch_typ == A_MTEvent)
swtch_typ = A_Coact;
#endif /* EventMon */
coexp_act = swtch_typ;
coswitch(ccp->cstate, ncp->cstate,first);
return coexp_act;
#endif /* Coexpr */
}
#ifdef Coexpr
/*
* new_context - determine what function to call to execute the new
* co-expression; this completes the context switch.
*/
void new_context(fsig,cargp)
int fsig;
dptr cargp;
{
#if COMPILER
(*coexpr_fnc)();
#else /* COMPILER */
interp(fsig, cargp);
#endif /* COMPILER */
}
#else /* Coexpr */
/* dummy new_context if co-expressions aren't supported */
void new_context(fsig,cargp)
int fsig;
dptr cargp;
{
}
#endif /* Coexpr */