Annotation of 43BSDTahoe/new/xns/compiler/procedures.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char RCSid[] = "$Header: procedures.c,v 2.2 86/11/11 09:49:06 jqj Exp $";
        !             3: #endif
        !             4: 
        !             5: /* $Log:       procedures.c,v $
        !             6:  * Revision 2.2  86/11/11  09:49:06  jqj
        !             7:  * Per Ed Flint, if a Courier procedure returns void, the server should still
        !             8:  * do a SendReturnMessage(0,0), so generate the proper code for this case.
        !             9:  * Note that this eventually implies (in xnslib/readwrite.c) that a writev()
        !            10:  * has an iovec with 0 length, which might tickle a kernel bug in some
        !            11:  * implementations.
        !            12:  * 
        !            13:  * Revision 2.1  86/06/06  07:28:49  jqj
        !            14:  * many mods for better symbol table management:  added CurrentModule,
        !            15:  *  made check_dependency, make_symbol, check_def set/use/use a symbol
        !            16:  *  table instead of a module name string, etc.  Result is that we can
        !            17:  *  now handle DEPENDS UPON 2 versions of same program.
        !            18:  * 
        !            19:  * Revision 2.0  85/11/21  07:21:43  jqj
        !            20:  * 4.3BSD standard release
        !            21:  * 
        !            22:  * Revision 1.5  85/05/06  08:13:31  jqj
        !            23:  * *** empty log message ***
        !            24:  * 
        !            25:  * Revision 1.5  85/05/06  08:13:31  jqj
        !            26:  * Almost Beta-test version.
        !            27:  * 
        !            28:  * Revision 1.4  85/03/26  06:10:21  jqj
        !            29:  * Revised public alpha-test version, released 26 March 1985
        !            30:  * 
        !            31:  * Revision 1.3  85/03/11  16:39:55  jqj
        !            32:  * Public alpha-test version, released 11 March 1985
        !            33:  * 
        !            34:  * Revision 1.2  85/02/21  11:05:39  jqj
        !            35:  * alpha test version
        !            36:  * 
        !            37:  * Revision 1.1  85/02/15  13:55:36  jqj
        !            38:  * Initial revision
        !            39:  * 
        !            40:  */
        !            41: 
        !            42: #define argname(p)     ((char *) car(caar(p)))
        !            43: #define argtype(p)     ((struct type *) cdar(p))
        !            44: 
        !            45: /*
        !            46:  * routines for generating procedures and errors
        !            47:  */
        !            48: 
        !            49: #include "compiler.h"
        !            50: 
        !            51: /*
        !            52:  * Generate client and server functions for procedure declarations.
        !            53:  */
        !            54: define_procedure_constant(symbol,typtr,value)
        !            55:        struct object *symbol;
        !            56:        struct type *typtr;
        !            57:        struct constant *value;
        !            58: {
        !            59:        struct type *resulttype;
        !            60:        char *procvalue;
        !            61:        char * resultname;
        !            62:        char buf[MAXSTR];
        !            63:        list p, q;
        !            64: 
        !            65:        if (recursive_flag)     /* don't bother to do anything for procs */
        !            66:                return;         /* in DEPENDS UPON modules */
        !            67:        if (typtr->type_constr != C_PROCEDURE)
        !            68:                error(FATAL, "internal error (define_procedure): not a procedure");
        !            69:        if (value->cn_constr != C_NUMERIC) {
        !            70:                error(ERROR,"Values of procedure constants must be numeric");
        !            71:                procvalue = "-1";
        !            72:        }
        !            73:        else
        !            74:                procvalue = value->cn_value;
        !            75:        /*
        !            76:         * RETURNS stuff:  coerce the result to be a single record
        !            77:         */
        !            78:        if (length(typtr->type_results) > 0) {
        !            79:                struct object *resultobj;
        !            80: 
        !            81:                resulttype = record_type(typtr->type_results);
        !            82:                sprintf(buf,"%sResults",name_of(symbol));
        !            83:                resultname = copy(buf);
        !            84:                resultobj = make_symbol(resultname,CurrentModule);
        !            85:                define_type(resultobj, resulttype);
        !            86:                /* replaces define_record_type(resulttype); */
        !            87:                typtr->type_results = cons( cons( cons((list)resultname, NIL),
        !            88:                                                  (list)resulttype), 
        !            89:                                            NIL);
        !            90:        }
        !            91:        /*
        !            92:         * REPORTS stuff:  check here to make sure the errors are all defined
        !            93:         */
        !            94:        for (p = typtr->type_errors, q = NIL; p != NIL; q = p, p = cdr(p)) {
        !            95:                struct object *sym;
        !            96:                sym = check_def((char *)car(p),CurrentModule);
        !            97:                if (sym == (struct object *)0) {
        !            98:                        error(ERROR,"Error constant %s not defined",
        !            99:                                (char*)car(p));
        !           100:                        if (q == NIL) typtr->type_errors = cdr(p);
        !           101:                        else cdr(q) = cdr(p);
        !           102:                }
        !           103:                else if (sym->o_class != O_CONSTANT
        !           104:                    || sym->o_constant->cn_constr != C_ERROR) {
        !           105:                        error(ERROR,"Symbol %s is not of appropriate type",
        !           106:                                name_of(sym));
        !           107:                        if (q == NIL) typtr->type_errors = cdr(p);
        !           108:                        else cdr(q) = cdr(p);
        !           109:                }
        !           110:        }
        !           111:        /*
        !           112:         * Argument stuff:  make sure all the argument types are defined
        !           113:         */
        !           114:        for (p = typtr->type_args; p != NIL; p = cdr(p)) {
        !           115:                if (typename(argtype(p)) == NULL) {
        !           116:                        struct object *name;
        !           117:                        name = make_symbol(gensym("T_p"),CurrentModule);
        !           118:                        define_type(name,argtype(p));
        !           119:                }
        !           120:        }
        !           121:        /*
        !           122:         * Actually generate code for this procedure
        !           123:         */
        !           124:        proc_functions(symbol->o_constant->cn_name, typtr, procvalue);
        !           125:        /*
        !           126:         * Save this procedure on the global procs for wrapup (server 
        !           127:         * dispatch code)
        !           128:         */
        !           129:        Procedures = cons(cons( (list)symbol->o_constant->cn_name,
        !           130:                                (list)procvalue ),
        !           131:                          Procedures);
        !           132: }
        !           133: 
        !           134: 
        !           135: /*
        !           136:  * Generate funcions for client and server calls to a procedure.
        !           137:  */
        !           138: proc_functions(proc_name, type, proc_number)
        !           139:        char *proc_name;
        !           140:        struct type *type;
        !           141:        char *proc_number;
        !           142: {
        !           143:        list p;
        !           144:        int nresults, fixed_size, variable_size;
        !           145:        struct type *t, *bt, *result_type;
        !           146:        char *result_name, *ref, *rtname;
        !           147: 
        !           148:        /*
        !           149:         * Make sure there is at most one result returned.
        !           150:         */
        !           151:        nresults = length(type->type_results);
        !           152:        if (nresults > 1) {
        !           153:                error(ERROR, "procedures that return multiple results are not supported");
        !           154:                return;
        !           155:        }
        !           156:        if (nresults) {
        !           157:                result_name = "_Results";
        !           158:                result_type = argtype(type->type_results);
        !           159:                rtname = typename(result_type);
        !           160:        } else {
        !           161:                rtname = "void";
        !           162:        }
        !           163: 
        !           164:        /*
        !           165:         * Server routine.
        !           166:         */
        !           167: 
        !           168:        fprintf(server, "\nextern %s %s();\n", rtname, proc_name);
        !           169:        fprintf(server,
        !           170: "\nserver_%s(_buf)\n\
        !           171: \tregister Unspecified *_buf;\n\
        !           172: {\n\
        !           173: \tregister Unspecified *_bp = _buf;\n\
        !           174: \tregister LongCardinal _n;\n",
        !           175:                proc_name);
        !           176:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           177:                t = argtype(p);
        !           178:                fprintf(server, "\t%s %s;\n", typename(t), argname(p));
        !           179:        }
        !           180:        if (nresults)
        !           181:                fprintf(server, "\t%s %s;\n", rtname, result_name);
        !           182:        fprintf(server, "\n");
        !           183:        /*
        !           184:         * Generate code to internalize the arguments.
        !           185:         */
        !           186:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           187:                t = argtype(p);
        !           188:                ref = refstr(t);
        !           189:                fprintf(server, "\t_bp += %s(%s%s, _bp);\n",
        !           190:                        xfn(INTERNALIZE, t), ref, argname(p));
        !           191:        }
        !           192:        /*
        !           193:         * Generate code to call the procedure.
        !           194:         */
        !           195:        if (nresults)
        !           196:                fprintf(server, "\t%s = %s(_serverConnection, 0",
        !           197:                        result_name, proc_name);
        !           198:        else
        !           199:                fprintf(server, "\t%s(_serverConnection, 0", proc_name);
        !           200:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           201:                fprintf(server, ", %s", argname(p));
        !           202:        }
        !           203:        fprintf(server, ");\n");
        !           204:        /*
        !           205:         * Generate code to externalize the result.
        !           206:         */
        !           207:        if (nresults) {
        !           208:                ref = refstr(result_type);
        !           209:                fprintf(server,
        !           210: "\t_n = sizeof_%s(%s%s);\n\
        !           211: \t_bp = Allocate(_n);\n\
        !           212: \t%s(%s%s, _bp);\n\
        !           213: \tSendReturnMessage(_n, _bp);\n\
        !           214: \tDeallocate(_bp);\n\
        !           215: }\n",
        !           216:                        rtname, ref, result_name,
        !           217:                        xfn(EXTERNALIZE, result_type), ref, result_name);
        !           218:        } else
        !           219:                fprintf(server,
        !           220: "\tSendReturnMessage( 0, _bp);\n\
        !           221: }\n"
        !           222:                        );
        !           223: 
        !           224:        /*
        !           225:         * Stub routine for client.
        !           226:         */
        !           227: 
        !           228:        fprintf(header, "\nextern %s %s();\n",
        !           229:                rtname, proc_name);
        !           230:        fprintf(client,
        !           231: "\n\
        !           232: %s\n\
        !           233: %s(_Connection, _BDTprocptr",
        !           234:                rtname, proc_name);
        !           235:        for (p = type->type_args; p != NIL; p = cdr(p))
        !           236:                fprintf(client, ", %s", argname(p));
        !           237:        fprintf(client, ")\n\
        !           238: \tCourierConnection *_Connection;\n\
        !           239: \tint (*_BDTprocptr)();\n\
        !           240: "
        !           241:                );
        !           242:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           243:                t = argtype(p);
        !           244:                fprintf(client, "\t%s %s;\n", typename(t), argname(p));
        !           245:        }
        !           246:        fprintf(client, "{\n");
        !           247:        if (nresults)
        !           248:                fprintf(client, "\t%s %s;\n", rtname, result_name);
        !           249:        fprintf(client,
        !           250: "\tregister Unspecified *_buf, *_bp;\n\
        !           251: \tBoolean _errorflag;\n\
        !           252: \tCardinal _errtype;\n"
        !           253:                );
        !           254:        /*
        !           255:         * Determine the size of the arguments.
        !           256:         * This is like the code in record_type().
        !           257:         */
        !           258:        fixed_size = 0;
        !           259:        variable_size = 0;
        !           260:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           261:                bt = argtype(p);
        !           262:                if (bt->type_xsize == -1) {
        !           263:                        variable_size = 1;
        !           264:                } else {
        !           265:                        fixed_size += bt->type_xsize;
        !           266:                }
        !           267:        }
        !           268:        if (!variable_size) {
        !           269:                /*
        !           270:                 * The argument list is fixed-size.
        !           271:                 */
        !           272:                fprintf(client,
        !           273: "\n\
        !           274: \t_buf = Allocate(%d);\n",
        !           275:                        fixed_size);
        !           276:        } else {
        !           277:                /*
        !           278:                 * There are some variable-size arguments.
        !           279:                 */
        !           280:                fprintf(client,
        !           281: "\tregister LongCardinal _n = %d;\n\
        !           282: \n",
        !           283:                        fixed_size);
        !           284:                for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           285:                        t = argtype(p);
        !           286:                        bt = t;
        !           287:                        if (bt->type_xsize != -1)
        !           288:                                continue;
        !           289:                        ref = refstr(bt);
        !           290:                        fprintf(client,
        !           291: "\t_n += sizeof_%s(%s%s);\n",
        !           292:                                typename(t), ref, argname(p));
        !           293:                }
        !           294:                fprintf(client,
        !           295: "\t_buf = Allocate(_n);\n"
        !           296:                        );
        !           297:        }
        !           298:        fprintf(client,
        !           299: "\t_bp = _buf;\n"
        !           300:                );
        !           301:        /*
        !           302:         * Generate code to externalize the arguments.
        !           303:         */
        !           304:        for (p = type->type_args; p != NIL; p = cdr(p)) {
        !           305:                t = argtype(p);
        !           306:                ref = refstr(t);
        !           307:                fprintf(client, "\t_bp += %s(%s%s, _bp);\n",
        !           308:                        xfn(EXTERNALIZE, t), ref, argname(p));
        !           309:        }
        !           310:        if (!variable_size) {
        !           311:                fprintf(client,
        !           312: "\tSendCallMessage(_Connection, %d, %d, %s, %d, _buf);\n",
        !           313:                        CurrentNumber, CurrentVersion,
        !           314:                        proc_number, fixed_size);
        !           315:        } else {
        !           316:                fprintf(client,
        !           317: "\tSendCallMessage(_Connection, %d, %d, %s, _n, _buf);\n",
        !           318:                        CurrentNumber, CurrentVersion,
        !           319:                        proc_number);
        !           320:        }
        !           321:        fprintf(client,
        !           322: "\tDeallocate(_buf);\n\
        !           323: \tMaybeCallBDTHandler(_Connection, _BDTprocptr);\n"
        !           324:                );
        !           325:        /*
        !           326:         * Generate code to receive the results and interpret them
        !           327:         * as errors
        !           328:         */
        !           329:        fprintf(client,
        !           330: "\t_bp = ReceiveReturnMessage(_Connection, &_errorflag);\n\
        !           331: \t_buf = _bp;\n\
        !           332: \tif (_errorflag) {\n\
        !           333: \t\t_bp += %s(&_errtype, _bp);\n\
        !           334: \t\tswitch (ERROR_OFFSET+_errtype) {\n",
        !           335:                xfn(INTERNALIZE, Cardinal_type)
        !           336:                        );
        !           337:        for (p = type->type_errors; p != NIL; p = cdr(p)) {
        !           338:                struct constant *errconst;
        !           339:                struct type *errtype;
        !           340:                errconst = (check_def((char *)car(p),CurrentModule))->o_constant;
        !           341:                errtype = (struct type *) cdr(errconst->cn_list);
        !           342:                if (errtype == TNIL)
        !           343:                        fprintf(client,
        !           344: "\t\tcase %s:\n\
        !           345: \t\t\traise(ERROR_OFFSET+_errtype, 0);\n\
        !           346: \t\t\t/*NOTREACHED*/\n",
        !           347:                                errconst->cn_name);
        !           348:                else
        !           349:                        fprintf(client,
        !           350: "\t\tcase %s: {\n\
        !           351: \t\t\tstatic %s _result;\n\
        !           352: \t\t\t_bp += %s(%s_result, _bp);\n\
        !           353: \t\t\traise(ERROR_OFFSET+_errtype, (char *) &_result);\n\
        !           354: \t\t\t/*NOTREACHED*/\n\
        !           355: \t\t\t}\n",
        !           356:                                errconst->cn_name,
        !           357:                                typename(errtype),
        !           358:                                xfn(INTERNALIZE, errtype), refstr(errtype)
        !           359:                                );
        !           360:        }
        !           361:        fprintf(client,
        !           362: "\t\tdefault:\n\
        !           363: \t\t\t/* don't know how to unpack this */\n\
        !           364: \t\t\traise(ERROR_OFFSET+_errtype, 0);\n\
        !           365: \t\t\t/*NOTREACHED*/\n\
        !           366: \t\t}\n"
        !           367:                );
        !           368:        /*
        !           369:         * Code to unpack results and return
        !           370:         */
        !           371:        if (nresults)
        !           372:                fprintf(client,
        !           373: "\t} else\n\
        !           374: \t\t_bp += %s(%s%s, _bp);\n\
        !           375: \tDeallocate(_buf);\n\
        !           376: \treturn (%s);\n\
        !           377: }\n",
        !           378:                        xfn(INTERNALIZE, result_type),
        !           379:                        refstr(result_type), result_name, result_name);
        !           380:        else
        !           381:                fprintf(client,
        !           382: "\t}\n\
        !           383: \tDeallocate(_buf);\n\
        !           384: }\n");
        !           385: }

unix.superglobalmegacorp.com

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