Annotation of 41BSD/cmd/pi/call.c, revision 1.1

1.1     ! root        1: /* Copyright (c) 1979 Regents of the University of California */
        !             2: 
        !             3: static char sccsid[] = "@(#)call.c 1.3 10/2/80";
        !             4: 
        !             5: #include "whoami.h"
        !             6: #include "0.h"
        !             7: #include "tree.h"
        !             8: #include "opcode.h"
        !             9: #include "objfmt.h"
        !            10: #ifdef PC
        !            11: #   include "pc.h"
        !            12: #   include "pcops.h"
        !            13: #endif PC
        !            14: 
        !            15: bool   slenflag = 0;
        !            16: bool   floatflag = 0;
        !            17: 
        !            18: /*
        !            19:  * Call generates code for calls to
        !            20:  * user defined procedures and functions
        !            21:  * and is called by proc and funccod.
        !            22:  * P is the result of the lookup
        !            23:  * of the procedure/function symbol,
        !            24:  * and porf is PROC or FUNC.
        !            25:  * Psbn is the block number of p.
        !            26:  */
        !            27: struct nl *
        !            28: call(p, argv, porf, psbn)
        !            29:        struct nl *p;
        !            30:        int *argv, porf, psbn;
        !            31: {
        !            32:        register struct nl *p1, *q;
        !            33:        int *r;
        !            34: 
        !            35: #      ifdef OBJ
        !            36:            int         cnt;
        !            37: #      endif OBJ
        !            38: #      ifdef PC
        !            39:            long        temp;
        !            40:            int         firsttime;
        !            41:            int         rettype;
        !            42: #      endif PC
        !            43: 
        !            44: #      ifdef OBJ
        !            45:            if (p->class == FFUNC || p->class == FPROC)
        !            46:                put(2, PTR_RV | cbn << 8+INDX, p->value[NL_OFFS]);
        !            47:            if (porf == FUNC)
        !            48:                    /*
        !            49:                     * Push some space
        !            50:                     * for the function return type
        !            51:                     */
        !            52:                    put2(O_PUSH, even(-width(p->type)));
        !            53: #      endif OBJ
        !            54: #      ifdef PC
        !            55:            if ( porf == FUNC ) {
        !            56:                switch( classify( p -> type ) ) {
        !            57:                    case TSTR:
        !            58:                    case TSET:
        !            59:                    case TREC:
        !            60:                    case TFILE:
        !            61:                    case TARY:
        !            62:                        temp = sizes[ cbn ].om_off -= width( p -> type );
        !            63:                        putlbracket( ftnno , -sizes[cbn].om_off );
        !            64:                        if (sizes[cbn].om_off < sizes[cbn].om_max) {
        !            65:                                sizes[cbn].om_max = sizes[cbn].om_off;
        !            66:                        }
        !            67:                        putRV( 0 , cbn , temp , P2STRTY );
        !            68:                }
        !            69:            }
        !            70:            switch ( p -> class ) {
        !            71:                case FUNC:
        !            72:                case PROC:
        !            73:                    {
        !            74:                        char    extname[ BUFSIZ ];
        !            75:                        char    *starthere;
        !            76:                        int     funcbn;
        !            77:                        int     i;
        !            78: 
        !            79:                        starthere = &extname[0];
        !            80:                        funcbn = p -> nl_block & 037;
        !            81:                        for ( i = 1 ; i < funcbn ; i++ ) {
        !            82:                            sprintf( starthere , EXTFORMAT , enclosing[ i ] );
        !            83:                            starthere += strlen( enclosing[ i ] ) + 1;
        !            84:                        }
        !            85:                        sprintf( starthere , EXTFORMAT , p -> symbol );
        !            86:                        starthere += strlen( p -> symbol ) + 1;
        !            87:                        if ( starthere >= &extname[ BUFSIZ ] ) {
        !            88:                            panic( "call namelength" );
        !            89:                        }
        !            90:                        putleaf( P2ICON , 0 , 0 , p2type( p ) , extname );
        !            91:                    }
        !            92:                    break;
        !            93:                case FFUNC:
        !            94:                case FPROC:
        !            95:                            /*
        !            96:                             *  start one of these:
        !            97:                             *  FRTN( frtn , ( *FCALL( frtn ) )(...args...) )
        !            98:                             */
        !            99:                        putleaf( P2ICON , 0 , 0 , p2type( p ) , "_FRTN" );
        !           100:                        putRV( 0 , cbn , p -> value[NL_OFFS] , P2PTR|P2STRTY );
        !           101:                        putleaf( P2ICON , 0 , 0
        !           102:                            , ADDTYPE( P2PTR , ADDTYPE( P2FTN , p2type( p ) ) )
        !           103:                            , "_FCALL" );
        !           104:                        putRV( 0 , cbn , p -> value[NL_OFFS] , P2PTR|P2STRTY );
        !           105:                        putop( P2CALL , p2type( p ) );
        !           106:                        break;
        !           107:                default:
        !           108:                        panic("call class");
        !           109:            }
        !           110:            firsttime = TRUE;
        !           111: #      endif PC
        !           112:        /*
        !           113:         * Loop and process each of
        !           114:         * arguments to the proc/func.
        !           115:         */
        !           116:        if ( p -> class == FUNC || p -> class == PROC ) {
        !           117:            for (p1 = p->chain; p1 != NIL; p1 = p1->chain) {
        !           118:                if (argv == NIL) {
        !           119:                        error("Not enough arguments to %s", p->symbol);
        !           120:                        return (NIL);
        !           121:                }
        !           122:                switch (p1->class) {
        !           123:                    case REF:
        !           124:                            /*
        !           125:                             * Var parameter
        !           126:                             */
        !           127:                            r = argv[1];
        !           128:                            if (r != NIL && r[0] != T_VAR) {
        !           129:                                    error("Expression given (variable required) for var parameter %s of %s", p1->symbol, p->symbol);
        !           130:                                    break;
        !           131:                            }
        !           132:                            q = lvalue( (int *) argv[1], MOD , LREQ );
        !           133:                            if (q == NIL)
        !           134:                                    break;
        !           135:                            if (q != p1->type) {
        !           136:                                    error("Parameter type not identical to type of var parameter %s of %s", p1->symbol, p->symbol);
        !           137:                                    break;
        !           138:                            }
        !           139:                            break;
        !           140:                    case VAR:
        !           141:                            /*
        !           142:                             * Value parameter
        !           143:                             */
        !           144: #                      ifdef OBJ
        !           145:                                q = rvalue(argv[1], p1->type , RREQ );
        !           146: #                      endif OBJ
        !           147: #                      ifdef PC
        !           148:                                    /*
        !           149:                                     * structure arguments require lvalues,
        !           150:                                     * scalars use rvalue.
        !           151:                                     */
        !           152:                                switch( classify( p1 -> type ) ) {
        !           153:                                    case TFILE:
        !           154:                                    case TARY:
        !           155:                                    case TREC:
        !           156:                                    case TSET:
        !           157:                                    case TSTR:
        !           158:                                        q = rvalue( argv[1] , p1 -> type , LREQ );
        !           159:                                        break;
        !           160:                                    case TINT:
        !           161:                                    case TSCAL:
        !           162:                                    case TBOOL:
        !           163:                                    case TCHAR:
        !           164:                                        precheck( p1 -> type , "_RANG4" , "_RSNG4" );
        !           165:                                        q = rvalue( argv[1] , p1 -> type , RREQ );
        !           166:                                        postcheck( p1 -> type );
        !           167:                                        break;
        !           168:                                    default:
        !           169:                                        q = rvalue( argv[1] , p1 -> type , RREQ );
        !           170:                                        if (  isa( p1 -> type  , "d" )
        !           171:                                           && isa( q , "i" ) ) {
        !           172:                                            putop( P2SCONV , P2DOUBLE );
        !           173:                                        }
        !           174:                                        break;
        !           175:                                }
        !           176: #                      endif PC
        !           177:                            if (q == NIL)
        !           178:                                    break;
        !           179:                            if (incompat(q, p1->type, argv[1])) {
        !           180:                                    cerror("Expression type clashed with type of value parameter %s of %s", p1->symbol, p->symbol);
        !           181:                                    break;
        !           182:                            }
        !           183: #                      ifdef OBJ
        !           184:                                if (isa(p1->type, "bcsi"))
        !           185:                                        rangechk(p1->type, q);
        !           186:                                if (q->class != STR)
        !           187:                                        convert(q, p1->type);
        !           188: #                      endif OBJ
        !           189: #                      ifdef PC
        !           190:                                switch( classify( p1 -> type ) ) {
        !           191:                                    case TFILE:
        !           192:                                    case TARY:
        !           193:                                    case TREC:
        !           194:                                    case TSET:
        !           195:                                    case TSTR:
        !           196:                                            putstrop( P2STARG
        !           197:                                                , p2type( p1 -> type )
        !           198:                                                , lwidth( p1 -> type )
        !           199:                                                , align( p1 -> type ) );
        !           200:                                }
        !           201: #                      endif PC
        !           202:                            break;
        !           203:                    case FFUNC:
        !           204:                            /*
        !           205:                             * function parameter
        !           206:                             */
        !           207:                            q = flvalue( (int *) argv[1] , FFUNC );
        !           208:                            if (q == NIL)
        !           209:                                    break;
        !           210:                            if (q != p1->type) {
        !           211:                                    error("Function type not identical to type of function parameter %s of %s", p1->symbol, p->symbol);
        !           212:                                    break;
        !           213:                            }
        !           214:                            break;
        !           215:                    case FPROC:
        !           216:                            /*
        !           217:                             * procedure parameter
        !           218:                             */
        !           219:                            q = flvalue( (int *) argv[1] , FPROC );
        !           220:                            if (q != NIL) {
        !           221:                                    error("Procedure parameter %s of %s cannot have a type", p1->symbol, p->symbol);
        !           222:                            }
        !           223:                            break;
        !           224:                    default:
        !           225:                            panic("call");
        !           226:                }
        !           227: #          ifdef PC
        !           228:                        /*
        !           229:                         *      if this is the nth (>1) argument,
        !           230:                         *      hang it on the left linear list of arguments
        !           231:                         */
        !           232:                    if ( firsttime ) {
        !           233:                            firsttime = FALSE;
        !           234:                    } else {
        !           235:                            putop( P2LISTOP , P2INT );
        !           236:                    }
        !           237: #          endif PC
        !           238:                argv = argv[2];
        !           239:            }
        !           240:            if (argv != NIL) {
        !           241:                    error("Too many arguments to %s", p->symbol);
        !           242:                    rvlist(argv);
        !           243:                    return (NIL);
        !           244:            }
        !           245:        } else if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           246:                /*
        !           247:                 *      formal routines can only have by-value parameters.
        !           248:                 *      this will lose for integer actuals passed to real
        !           249:                 *      formals, and strings which people want blank padded.
        !           250:                 */
        !           251: #          ifdef OBJ
        !           252:                cnt = 0;
        !           253: #          endif OBJ
        !           254:            for ( ; argv != NIL ; argv = argv[2] ) {
        !           255: #              ifdef OBJ
        !           256:                    q = rvalue(argv[1], NIL, RREQ );
        !           257:                    cnt += even(lwidth(q));
        !           258: #              endif OBJ
        !           259: #              ifdef PC
        !           260:                        /*
        !           261:                         * structure arguments require lvalues,
        !           262:                         * scalars use rvalue.
        !           263:                         */
        !           264:                    codeoff();
        !           265:                    p1 = rvalue( argv[1] , NIL , RREQ );
        !           266:                    codeon();
        !           267:                    switch( classify( p1 ) ) {
        !           268:                        case TSTR:
        !           269:                            if ( p1 -> class == STR && slenflag == 0 ) {
        !           270:                                if ( opt( 's' ) ) {
        !           271:                                    standard();
        !           272:                                } else {
        !           273:                                    warning();
        !           274:                                }
        !           275:                                error("Implementation can't construct equal length strings");
        !           276:                                slenflag++;
        !           277:                            }
        !           278:                            /* and fall through */
        !           279:                        case TFILE:
        !           280:                        case TARY:
        !           281:                        case TREC:
        !           282:                        case TSET:
        !           283:                            q = rvalue( argv[1] , p1 , LREQ );
        !           284:                            break;
        !           285:                        case TINT:
        !           286:                            if ( floatflag == 0 ) {
        !           287:                                if ( opt( 's' ) ) {
        !           288:                                    standard();
        !           289:                                } else {
        !           290:                                    warning();
        !           291:                                }
        !           292:                                error("Implementation can't coerice integer to real");
        !           293:                                floatflag++;
        !           294:                            }
        !           295:                            /* and fall through */
        !           296:                        case TSCAL:
        !           297:                        case TBOOL:
        !           298:                        case TCHAR:
        !           299:                        default:
        !           300:                            q = rvalue( argv[1] , p1 , RREQ );
        !           301:                            break;
        !           302:                    }
        !           303:                    switch( classify( p1 ) ) {
        !           304:                        case TFILE:
        !           305:                        case TARY:
        !           306:                        case TREC:
        !           307:                        case TSET:
        !           308:                        case TSTR:
        !           309:                                putstrop( P2STARG , p2type( p1 ) ,
        !           310:                                    lwidth( p1 ) , align( p1 ) );
        !           311:                    }
        !           312:                        /*
        !           313:                         *      if this is the nth (>1) argument,
        !           314:                         *      hang it on the left linear list of arguments
        !           315:                         */
        !           316:                    if ( firsttime ) {
        !           317:                            firsttime = FALSE;
        !           318:                    } else {
        !           319:                            putop( P2LISTOP , P2INT );
        !           320:                    }
        !           321: #              endif PC
        !           322:            }
        !           323:        } else {
        !           324:            panic("call class");
        !           325:        }
        !           326: #      ifdef OBJ
        !           327:            if ( p -> class == FFUNC || p -> class == FPROC ) {
        !           328:                put(2, PTR_RV | cbn << 8+INDX, p->value[NL_OFFS]);
        !           329:                put(2, O_FCALL, cnt);
        !           330:                put(2, O_FRTN, even(lwidth(p->type)));
        !           331:            } else {
        !           332:                put2(O_CALL | psbn << 8+INDX, p->entloc);
        !           333:            }
        !           334: #      endif OBJ
        !           335: #      ifdef PC
        !           336:            if ( porf == FUNC ) {
        !           337:                rettype = p2type( p -> type );
        !           338:                switch ( classify( p -> type ) ) {
        !           339:                    case TBOOL:
        !           340:                    case TCHAR:
        !           341:                    case TINT:
        !           342:                    case TSCAL:
        !           343:                    case TDOUBLE:
        !           344:                    case TPTR:
        !           345:                        if ( firsttime ) {
        !           346:                                putop( P2UNARY P2CALL , rettype );
        !           347:                        } else {
        !           348:                                putop( P2CALL , rettype );
        !           349:                        }
        !           350:                        if (p -> class == FFUNC || p -> class == FPROC ) {
        !           351:                            putop( P2LISTOP , P2INT );
        !           352:                            putop( P2CALL , rettype );
        !           353:                        }
        !           354:                        break;
        !           355:                    default:
        !           356:                        if ( firsttime ) {
        !           357:                                putstrop( P2UNARY P2STCALL
        !           358:                                        , ADDTYPE( rettype , P2PTR )
        !           359:                                        , lwidth( p -> type )
        !           360:                                        , align( p -> type ) );
        !           361:                        } else {
        !           362:                                putstrop( P2STCALL
        !           363:                                        , ADDTYPE( rettype , P2PTR )
        !           364:                                        , lwidth( p -> type )
        !           365:                                        , align( p -> type ) );
        !           366:                        }
        !           367:                        if (p -> class == FFUNC || p -> class == FPROC ) {
        !           368:                            putop( P2LISTOP , P2INT );
        !           369:                            putop( P2CALL , ADDTYPE( rettype , P2PTR ) );
        !           370:                        }
        !           371:                        putstrop( P2STASG , rettype , lwidth( p -> type )
        !           372:                                , align( p -> type ) );
        !           373:                        putLV( 0 , cbn , temp , rettype );
        !           374:                        putop( P2COMOP , P2INT );
        !           375:                        break;
        !           376:                }
        !           377:            } else {
        !           378:                if ( firsttime ) {
        !           379:                        putop( P2UNARY P2CALL , P2INT );
        !           380:                } else {
        !           381:                        putop( P2CALL , P2INT );
        !           382:                }
        !           383:                if (p -> class == FFUNC || p -> class == FPROC ) {
        !           384:                    putop( P2LISTOP , P2INT );
        !           385:                    putop( P2CALL , P2INT );
        !           386:                }
        !           387:                putdot( filename , line );
        !           388:            }
        !           389: #      endif PC
        !           390:        return (p->type);
        !           391: }
        !           392: 
        !           393: rvlist(al)
        !           394:        register int *al;
        !           395: {
        !           396: 
        !           397:        for (; al != NIL; al = al[2])
        !           398:                rvalue( (int *) al[1], NLNIL , RREQ );
        !           399: }

unix.superglobalmegacorp.com

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