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 >
Text File  |  2001-12-12  |  8KB  |  316 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. void 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.    sblkp->es_argp = (dptr)newsp;  /* args are first thing on stack */
  82.  
  83. #endif                    /* COMPILER */
  84.  
  85.    /*
  86.     * Copy arguments onto new stack.
  87.     */
  88.    dsp = sblkp->es_argp;
  89.    dp = rblkp->elems;
  90.    for (i = 1; i <=  na; i++)
  91.       *dsp++ = *dp++;
  92.  
  93.    /*
  94.     * Set up state variables and initialize procedure frame.
  95.     */
  96. #if COMPILER
  97.    sblkp->es_pfp = &sblkp->pf;
  98.    sblkp->es_tend = &sblkp->pf.tend;
  99.    sblkp->pf.old_pfp = NULL;
  100.    sblkp->pf.rslt = NULL;
  101.    sblkp->pf.succ_cont = NULL;
  102.    sblkp->pf.tend.previous = NULL;
  103.    sblkp->pf.tend.num = nl + na + nt;
  104.    sblkp->es_actstk = NULL;
  105. #else                    /* COMPILER */
  106.    *((struct pf_marker *)dsp) = rblkp->pfmkr;
  107.    sblkp->es_pfp = (struct pf_marker *)dsp;
  108.    sblkp->es_tend = NULL;
  109.    dsp = (dptr)((word *)dsp + Vwsizeof(*pfp));
  110.    sblkp->es_ipc.opnd = rblkp->ep;
  111.    sblkp->es_gfp = 0;
  112.    sblkp->es_efp = 0;
  113.    sblkp->es_ilevel = 0;
  114. #endif                    /* COMPILER */
  115.    sblkp->tvalloc = NULL;
  116.  
  117.    /*
  118.     * Copy locals into the co-expression.
  119.     */
  120. #if COMPILER
  121.    dsp = sblkp->pf.tend.d;
  122. #endif                    /* COMPILER */
  123.    for (i = 1; i <= nl; i++)
  124.       *dsp++ = *dp++;
  125.  
  126. #if COMPILER
  127.    /*
  128.     * Initialize temporary variables.
  129.     */
  130.    for (i = 1; i <= nt; i++)
  131.       *dsp++ = nulldesc;
  132. #else                    /* COMPILER */
  133.    /*
  134.     * Push two null descriptors on the stack.
  135.     */
  136.    *dsp++ = nulldesc;
  137.    *dsp++ = nulldesc;
  138.  
  139.    sblkp->es_sp = (word *)dsp - 1;
  140. #endif                    /* COMPILER */
  141.  
  142. #endif                    /* Coexpr */
  143.    }
  144.  
  145. /*
  146.  * co_chng - high-level co-expression context switch.
  147.  */
  148. int co_chng(ncp, valloc, rsltloc, swtch_typ, first)
  149. struct b_coexpr *ncp;
  150. struct descrip *valloc; /* location of value being transmitted */
  151. struct descrip *rsltloc;/* location to put result */
  152. int swtch_typ;          /* A_Coact, A_Coret, A_Cofail, or A_MTEvent */
  153. int first;
  154. {
  155. #ifndef Coexpr
  156.    syserr("co_chng() called, but co-expressions not implemented");
  157. #else                    /* Coexpr */
  158.    register struct b_coexpr *ccp;
  159.    static int coexp_act;     /* used to pass signal across activations */
  160.                              /* back to whomever activates, if they care */
  161.  
  162.    ccp = (struct b_coexpr *)BlkLoc(k_current);
  163.  
  164. #if !COMPILER
  165. #ifdef EventMon
  166.    switch(swtch_typ) {
  167.       /*
  168.        * A_MTEvent does not generate an event.
  169.        */
  170.       case A_MTEvent:
  171.      break;
  172.       case A_Coact:
  173.          EVValX(ncp,E_Coact);
  174.      if (!is:null(curpstate->eventmask)) {
  175.         curpstate->parent->eventsource.dword = D_Coexpr;
  176.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  177.         }
  178.      break;
  179.       case A_Coret:
  180.          EVValX(ncp,E_Coret);
  181.      if (!is:null(curpstate->eventmask)) {
  182.         curpstate->parent->eventsource.dword = D_Coexpr;
  183.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  184.         }
  185.      break;
  186.       case A_Cofail:
  187.          EVValX(ncp,E_Cofail);
  188.      if (!is:null(curpstate->eventmask) && ncp->program == curpstate) {
  189.         curpstate->parent->eventsource.dword = D_Coexpr;
  190.         BlkLoc(curpstate->parent->eventsource) = (union block *)ncp;
  191.         }
  192.      break;
  193.       }
  194. #endif                    /* EventMon */
  195. #endif                    /* COMPILER */
  196.  
  197.    /*
  198.     * Determine if we need to transmit a value.
  199.     */
  200.    if (valloc != NULL) {
  201.  
  202. #if !COMPILER
  203.       /*
  204.        * Determine if we need to dereference the transmitted value.
  205.        */
  206.       if (Var(*valloc))
  207.          retderef(valloc, (word *)glbl_argp, sp);
  208. #endif                    /* COMPILER */
  209.  
  210.       if (ncp->tvalloc != NULL)
  211.          *ncp->tvalloc = *valloc;
  212.       }
  213.    ncp->tvalloc = NULL;
  214.    ccp->tvalloc = rsltloc;
  215.  
  216.    /*
  217.     * Save state of current co-expression.
  218.     */
  219.    ccp->es_pfp = pfp;
  220.    ccp->es_argp = glbl_argp;
  221.    ccp->es_tend = tend;
  222.  
  223. #if !COMPILER
  224.    ccp->es_efp = efp;
  225.    ccp->es_gfp = gfp;
  226.    ccp->es_ipc = ipc;
  227.    ccp->es_sp = sp;
  228.    ccp->es_ilevel = ilevel;
  229. #endif                    /* COMPILER */
  230.  
  231. #if COMPILER
  232.    if (line_info) {
  233.       ccp->file_name = file_name;
  234.       ccp->line_num = line_num;
  235.       file_name = ncp->file_name;
  236.       line_num = ncp->line_num;
  237.       }
  238. #endif                    /* COMPILER */
  239.  
  240. #if COMPILER
  241.    if (debug_info)
  242. #endif                    /* COMPILER */
  243.       if (k_trace)
  244. #ifdef EventMon
  245.      if (swtch_typ != A_MTEvent)
  246. #endif                    /* EventMon */
  247.          cotrace(ccp, ncp, swtch_typ, valloc);
  248.  
  249.    /*
  250.     * Establish state for new co-expression.
  251.     */
  252.    pfp = ncp->es_pfp;
  253.    tend = ncp->es_tend;
  254.  
  255. #if !COMPILER
  256.    efp = ncp->es_efp;
  257.    gfp = ncp->es_gfp;
  258.    ipc = ncp->es_ipc;
  259.    sp = ncp->es_sp;
  260.    ilevel = (int)ncp->es_ilevel;
  261. #endif                    /* COMPILER */
  262.  
  263. #if !COMPILER
  264. #ifdef MultiThread
  265.    /*
  266.     * Enter the program state of the co-expression being activated
  267.     */
  268.    ENTERPSTATE(ncp->program);
  269. #endif                    /* MultiThread */
  270. #endif                    /* COMPILER */
  271.  
  272.    glbl_argp = ncp->es_argp;
  273.    BlkLoc(k_current) = (union block *)ncp;
  274.  
  275. #if COMPILER
  276.    coexpr_fnc = ncp->fnc;
  277. #endif                    /* COMPILER */
  278.  
  279. #ifdef EventMon
  280.    /*
  281.     * From here on out, A_MTEvent looks like a A_Coact.
  282.     */
  283.    if (swtch_typ == A_MTEvent)
  284.       swtch_typ = A_Coact;
  285. #endif                    /* EventMon */
  286.  
  287.    coexp_act = swtch_typ;
  288.    coswitch(ccp->cstate, ncp->cstate,first);
  289.    return coexp_act;
  290. #endif                    /* Coexpr */
  291.    }
  292.  
  293. #ifdef Coexpr
  294. /*
  295.  * new_context - determine what function to call to execute the new
  296.  *  co-expression; this completes the context switch.
  297.  */
  298. void new_context(fsig,cargp)
  299. int fsig;
  300. dptr cargp;
  301.    {
  302. #if COMPILER
  303.    (*coexpr_fnc)();
  304. #else                    /* COMPILER */
  305.    interp(fsig, cargp);
  306. #endif                    /* COMPILER */
  307.    }
  308. #else                    /* Coexpr */
  309. /* dummy new_context if co-expressions aren't supported */
  310. void new_context(fsig,cargp)
  311. int fsig;
  312. dptr cargp;
  313.    {
  314.    }
  315. #endif                    /* Coexpr */
  316.