Annotation of researchv10dc/cmd/icon/src/iconx/invoke.c, revision 1.1.1.1

1.1       root        1: #include "../h/rt.h"
                      2: 
                      3: #define PerilDelta 100
                      4: extern word *stackend;         /* End of main interpreter stack */
                      5: /*
                      6:  * invoke -- Perform setup for invocation.  
                      7:  */
                      8: invoke(nargs,cargp,n)
                      9: struct descrip **cargp;
                     10: int nargs, *n;
                     11: {
                     12:    register struct pf_marker *newpfp;
                     13:    register struct descrip *newargp;
                     14:    register word *newsp = sp;
                     15:    register word i;
                     16:    struct b_proc *proc;
                     17:    int nparam;
                     18:    long longint;
                     19:    char strbuf[MaxCvtLen];
                     20: 
                     21:    /*
                     22:     * Point newargp at Arg0 and dereference it.
                     23:     */
                     24:    newargp = (struct descrip *)(sp - 1) - nargs;
                     25:    DeRef(newargp[0]);
                     26:    
                     27:    /*
                     28:     * See what course the invocation is to take.
                     29:     */
                     30:    if (newargp->dword != D_Proc) {
                     31:       /*
                     32:        * Arg0 is not a procedure.
                     33:        */
                     34:       if (cvint(&newargp[0], &longint) == T_Integer) {
                     35:          /*
                     36:          * Arg0 is an integer, select result.
                     37:          */
                     38:          i = cvpos(longint, (word)nargs);
                     39:          if (i > nargs)
                     40:             return I_Goal_Fail;
                     41:          newargp[0] = newargp[i];
                     42:          sp = (word *)newargp + 1;
                     43:          return I_Continue;
                     44:          }
                     45:       else {
                     46:          /*
                     47:          * See if Arg0 can be converted to a string that names a procedure
                     48:          *  or operator.  If not, generate run-time error 106.
                     49:          */
                     50:          if (cvstr(&newargp[0],strbuf) == NULL || strprc(&newargp[0],(word)nargs) == 0)
                     51:             runerr(106, newargp);
                     52:         }
                     53:       }
                     54:    
                     55:    /*
                     56:     * newargp[0] is now a descriptor suitable for invocation.  Dereference
                     57:     *  the supplied arguments.
                     58:     */
                     59:    for (i = 1; i <= nargs; i++)
                     60:       DeRef(newargp[i]);
                     61:       
                     62:    /*
                     63:     * Adjust the argument list to conform to what the routine being invoked
                     64:     *  expects (proc->nparam).  If nparam is -1, the number of arguments
                     65:     *  is variable and no adjustment is required.  If too many arguments
                     66:     *  were supplied, adjusting the stack pointer is all that is necessary.
                     67:     *  If too few arguments were supplied, null descriptors are pushed
                     68:     *  for each missing argument.
                     69:     */
                     70:    proc = (struct b_proc *)BlkLoc(newargp[0]);
                     71:    nparam = proc->nparam;
                     72:    if (nparam != -1) {
                     73:       if (nargs > nparam)
                     74:          newsp -= (nargs - nparam) * 2;
                     75:       else if (nargs < nparam) {
                     76:          i = nparam - nargs;
                     77:          while (i--) {
                     78:             *++newsp = D_Null;
                     79:             *++newsp = 0;
                     80:             }
                     81:          }
                     82:       nargs = nparam;
                     83:       }
                     84: 
                     85:    if (proc->ndynam < 0) {
                     86:       /*
                     87:        * A built-in procedure is being invoked, so nothing else here
                     88:        *  needs to be done.
                     89:        */
                     90:       *n = nargs;
                     91:       *cargp = newargp;
                     92:       sp = newsp;
                     93:       if ((nparam == -1) || (proc->ndynam == -2))
                     94:          return I_Vararg;
                     95:       else
                     96:          return I_Builtin;
                     97:       }
                     98: 
                     99:    /*
                    100:     * Make a stab at catching interpreter stack overflow.  This does
                    101:     * nothing for invocation in a co-expression other than &main.
                    102:     */
                    103:    if (BlkLoc(current) == BlkLoc(k_main) && (sp + PerilDelta) > stackend)
                    104:       runerr(301, NULL);
                    105:    /*
                    106:     * Build the procedure frame.
                    107:     */
                    108:    newpfp = (struct pf_marker *)(newsp + 1);
                    109:    newpfp->pf_nargs = nargs;
                    110:    newpfp->pf_argp = argp;
                    111:    newpfp->pf_pfp = pfp;
                    112:    newpfp->pf_ilevel = ilevel;
                    113: 
                    114:    newpfp->pf_ipc = ipc;
                    115:    newpfp->pf_gfp = gfp;
                    116:    newpfp->pf_efp = efp;
                    117: 
                    118:    argp = newargp;
                    119:    pfp = newpfp;
                    120:    newsp += Vwsizeof(*pfp);
                    121:    
                    122:    /*
                    123:     * Point ipc at the icode entry point of the procedure being invoked.
                    124:     */
                    125:    ipc = (word *)proc->entryp.icode;
                    126:    efp = 0;
                    127:    gfp = 0;
                    128: 
                    129:    newpfp->pf_line = line;
                    130: 
                    131:    /*
                    132:     * If tracing is on, use ctrace to generate a message.
                    133:     */   
                    134:    if (k_trace != 0)
                    135:       ctrace(proc, nargs, &newargp[1]);
                    136: 
                    137:    /*
                    138:     * Push a null descriptor on the stack for each dynamic local.
                    139:     */
                    140:    for (i = proc->ndynam; i > 0; i--) {
                    141:       *++newsp = D_Null;
                    142:       *++newsp = 0;
                    143:       }
                    144: 
                    145:    sp = newsp;
                    146:    k_level++;
                    147:    return I_Continue;
                    148: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.