/* * 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 */