home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / historic / v92.tgz / v92.tar / v92 / src / runtime / rcoexpr.r < prev    next >
Text File  |  1996-03-22  |  8KB  |  311 lines

  1. /*
  2.  * File: rcoexpr.r -- co_init, co_chng
  3.  */
  4.  
  5. #if COMPILER
  6. static continuation coexpr_fnc;  /* function to call after switching stacks */
  7. #endif                    /* COMPILER */
  8.  
  9. /*
  10.  * co_init - use the contents of the refresh block to initialize the
  11.  *  co-expression.
  12.  */
  13. novalue co_init(sblkp)
  14. struct b_coexpr *sblkp;
  15. {
  16. #ifndef Coexpr
  17.    syserr("co_init() called, but co-expressions not implemented");
  18. #else                    /* Coexpr */
  19.    register word *newsp;
  20.    register struct b_refresh *rblkp;
  21.    register dptr dp, dsp;
  22.    int frame_size;
  23.    word stack_strt;
  24.    int na, nl, nt, i;
  25.  
  26.    /*
  27.     * Get pointer to refresh block.
  28.     */
  29.    rblkp = (struct b_refresh *)BlkLoc(sblkp->freshblk);
  30.  
  31. #if COMPILER
  32.    na = rblkp->nargs;                /* number of arguments */
  33.    nl = rblkp->nlocals;              /* number of locals */
  34.    nt = rblkp->ntemps;               /* number of temporaries */
  35.  
  36.    /*
  37.     * The C stack must be aligned on the correct boundary. For up-growing
  38.     *  stacks, the C stack starts after the initial procedure frame of
  39.     *  the co-expression block. For down-growing stacks, the C stack starts
  40.     *  at the last word of the co-expression block.
  41.     */
  42. #ifdef UpStack
  43.    frame_size = sizeof(struct p_frame) + sizeof(struct descrip) * (nl + na +
  44.       nt - 1) + rblkp->wrk_size;
  45.    stack_strt = (word)((char *)&sblkp->pf + frame_size + StackAlign*WordSize);
  46. #else                    /* UpStack */
  47.    stack_strt = (word)((char *)sblkp + stksize - WordSize);
  48. #endif                    /* UpStack */
  49.    sblkp->cstate[0] = stack_strt & ~(WordSize * StackAlign - 1);
  50.  
  51.    sblkp->es_argp = &sblkp->pf.tend.d[nl + nt];   /* args follow temporaries */
  52.  
  53. #else                    /* COMPILER */
  54.  
  55.    na = (rblkp->pfmkr).pf_nargs + 1; /* number of arguments */
  56.    nl = (int)rblkp->numlocals;       /* number of locals */
  57.  
  58.    /*
  59.     * The interpreter stack starts at word after co-expression stack block.
  60.     *  C stack starts at end of stack region on machines with down-growing C
  61.     *  stacks and somewhere in the middle of the region.
  62.     *
  63.     * The C stack is aligned on a doubleword boundary.    For up-growing
  64.     *  stacks, the C stack starts in the middle of the stack portion
  65.     *  of the static block.  For down-growing stacks, the C stack starts
  66.     *  at the last word of the static block.
  67.     */
  68.  
  69.    newsp = (word *)((char *)sblkp + sizeof(struct b_coexpr));
  70.  
  71. #ifdef UpStack
  72.    sblkp->cstate[0] =
  73.       ((word)((char *)sblkp + (stksize - sizeof(*sblkp))/2)
  74.          &~((word)WordSize*StackAlign-1));
  75. #else                    /* UpStack */
  76.    sblkp->cstate[0] =
  77.     ((word)((char *)sblkp + stksize - WordSize)
  78.            &~((word)WordSize*StackAlign-1));
  79. #endif                    /* UpStack */
  80.  
  81. #ifdef CoProcesses
  82.    sblkp->cstate[1] = 0;
  83. #endif
  84.  
  85.    sblkp->es_argp = (dptr)newsp;  /* args are first thing on stack */
  86.  
  87. #endif                    /* COMPILER */
  88.  
  89.    /*
  90.     * Copy arguments onto new stack.
  91.     */
  92.    dsp = sblkp->es_argp;
  93.    dp = rblkp->elems;
  94.    for (i = 1; i <=  na; i++)
  95.       *dsp++ = *dp++;
  96.  
  97.    /*
  98.     * Set up state variables and initialize procedure frame.
  99.     */
  100. #if COMPILER
  101.    sblkp->es_pfp = &sblkp->pf;
  102.    sblkp->es_tend = &sblkp->pf.tend;
  103.    sblkp->pf.old_pfp = NULL;
  104.    sblkp->pf.rslt = NULL;
  105.    sblkp->pf.succ_cont = NULL;
  106.    sblkp->pf.tend.previous = NULL;
  107.    sblkp->pf.tend.num = nl + na + nt;
  108.    sblkp->es_actstk = NULL;
  109. #else                    /* COMPILER */
  110.    *((struct pf_marker *)dsp) = rblkp->pfmkr;
  111.    sblkp->es_pfp = (struct pf_marker *)dsp;
  112.    sblkp->es_tend = NULL;
  113.    dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
  114.    sblkp->es_ipc.opnd = rblkp->ep;
  115.    sblkp->es_gfp = 0;
  116.    sblkp->es_efp = 0;
  117.    sblkp->es_ilevel = 0;
  118. #endif                    /* COMPILER */
  119.    sblkp->tvalloc = NULL;
  120.  
  121.    /*
  122.     * Copy locals into the co-expression.
  123.     */
  124. #if COMPILER
  125.    dsp = sblkp->pf.tend.d;
  126. #endif                    /* COMPILER */
  127.    for (i = 1; i <= nl; i++)
  128.       *dsp++ = *dp++;
  129.  
  130. #if COMPILER
  131.    /*
  132.     * Initialize temporary variables.
  133.     */
  134.    for (i = 1; i <= nt; i++)
  135.       *dsp++ = nulldesc;
  136. #else                    /* COMPILER */
  137.    /*
  138.     * Push two null descriptors on the stack.
  139.     */
  140.    *dsp++ = nulldesc;
  141.    *dsp++ = nulldesc;
  142.  
  143.    sblkp->es_sp = (word *)dsp - 1;
  144. #endif                    /* COMPILER */
  145.  
  146. #endif                    /* Coexpr */
  147.    }
  148.  
  149. /*
  150.  * co_chng - high-level co-expression context switch.
  151.  */
  152. int co_chng(ncp, valloc, rsltloc, swtch_typ, first)
  153. struct b_coexpr *ncp;
  154. struct descrip *valloc; /* location of value being transmitted */
  155. struct descrip *rsltloc;/* location to put result */
  156. int swtch_typ;          /* A_Coact, A_Coret, A_Cofail, or A_MTEvent */
  157. int first;
  158. {
  159. #ifndef Coexpr
  160.    syserr("co_chng() called, but co-expressions not implemented");
  161. #else                        /* Coexpr */
  162.    register struct b_coexpr *ccp;
  163.    static int coexp_act;     /* used to pass signal across activations */
  164.                              /* back to whomever activates, if they care */
  165.  
  166.    ccp = (struct b_coexpr *)BlkLoc(k_current);
  167.  
  168. #if !COMPILER
  169. #ifdef EventMon
  170.    switch(swtch_typ) {
  171.       /*
  172.        * A_MTEvent does not generate an event.
  173.        * From here on out, it looks like a Coact.
  174.        */
  175.       case A_MTEvent:
  176.      swtch_typ = A_Coact;
  177.      break;
  178.       case A_Coact:
  179.          EVValX(ncp,E_Coact);
  180.      if (!is:null(curpstate->eventmask)) {
  181.         curpstate->parent->eventsource.dword = D_Coexpr;
  182.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  183.         }
  184.      break;
  185.       case A_Coret:
  186.          EVValX(ncp,E_Coret);
  187.      if (!is:null(curpstate->eventmask)) {
  188.         curpstate->parent->eventsource.dword = D_Coexpr;
  189.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  190.         }
  191.      break;
  192.       case A_Cofail:
  193.          EVValX(ncp,E_Cofail);
  194.      if (!is:null(curpstate->eventmask) && ncp->program == curpstate) {
  195.         curpstate->parent->eventsource.dword = D_Coexpr;
  196.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  197.         }
  198.      break;
  199.       }
  200. #endif                        /* EventMon */
  201. #endif                    /* COMPILER */
  202.  
  203.    /*
  204.     * Determine if we need to transmit a value.
  205.     */
  206.    if (valloc != NULL) {
  207.  
  208. #if !COMPILER
  209.       /*
  210.        * Determine if we need to dereference the transmitted value. 
  211.        */
  212.       if (Var(*valloc))
  213.          retderef(valloc, (word *)argp, sp);
  214. #endif                    /* COMPILER */
  215.  
  216.       if (ncp->tvalloc != NULL)
  217.          *ncp->tvalloc = *valloc;
  218.       }
  219.    ncp->tvalloc = NULL;
  220.    ccp->tvalloc = rsltloc;
  221.  
  222.    /*
  223.     * Save state of current co-expression.
  224.     */
  225.    ccp->es_pfp = pfp;
  226.    ccp->es_argp = argp;
  227.    ccp->es_tend = tend;
  228.  
  229. #if !COMPILER
  230.    ccp->es_efp = efp;
  231.    ccp->es_gfp = gfp;
  232.    ccp->es_ipc = ipc;
  233.    ccp->es_sp = sp;
  234.    ccp->es_ilevel = ilevel;
  235. #endif                    /* COMPILER */
  236.  
  237. #if COMPILER
  238.    if (line_info) {
  239.       ccp->file_name = file_name;
  240.       ccp->line_num = line_num;
  241.       file_name = ncp->file_name;
  242.       line_num = ncp->line_num;
  243.       }
  244. #endif                    /* COMPILER */
  245.  
  246. #if COMPILER
  247.    if (debug_info)
  248. #endif                    /* COMPILER */
  249.       if (k_trace)
  250.          cotrace(ccp, ncp, swtch_typ, valloc);
  251.  
  252.    /*
  253.     * Establish state for new co-expression.
  254.     */
  255.    pfp = ncp->es_pfp;
  256.    argp = ncp->es_argp;
  257.    tend = ncp->es_tend;
  258.  
  259. #if !COMPILER
  260.    efp = ncp->es_efp;
  261.    gfp = ncp->es_gfp;
  262.    ipc = ncp->es_ipc;
  263.    sp = ncp->es_sp;
  264.    ilevel = (int)ncp->es_ilevel;
  265. #endif                    /* COMPILER */
  266.  
  267. #if !COMPILER
  268. #ifdef MultiThread
  269.    /*
  270.     * Enter the program state of the co-expression being activated
  271.     */
  272.    ENTERPSTATE(ncp->program);
  273. #endif                        /* MultiThread */
  274. #endif                    /* COMPILER */
  275.  
  276.    BlkLoc(k_current) = (union block *)ncp;
  277.  
  278. #if COMPILER
  279.    coexpr_fnc = ncp->fnc;
  280. #endif                    /* COMPILER */
  281.  
  282.    coexp_act = swtch_typ;
  283.    coswitch(ccp->cstate, ncp->cstate,first);
  284.    return coexp_act;
  285. #endif                        /* Coexpr */
  286.    }
  287.  
  288. #ifdef Coexpr
  289. /*
  290.  * new_context - determine what function to call to execute the new
  291.  *  co-expression; this completes the context switch.
  292.  */
  293. novalue new_context(fsig,cargp)
  294. int fsig;
  295. dptr cargp;
  296.    {
  297. #if COMPILER
  298.    (*coexpr_fnc)();
  299. #else                    /* COMPILER */
  300.    interp(fsig, cargp);
  301. #endif                    /* COMPILER */
  302.    }
  303. #else                    /* Coexpr */
  304. /* dummy new_context if co-expressions aren't supported */
  305. novalue new_context(fsig,cargp)
  306. int fsig;
  307. dptr cargp;
  308.    {
  309.    }
  310. #endif                    /* Coexpr */
  311.