diff options
Diffstat (limited to 'mig/routine.h')
-rw-r--r-- | mig/routine.h | 401 |
1 files changed, 0 insertions, 401 deletions
diff --git a/mig/routine.h b/mig/routine.h deleted file mode 100644 index f80a174..0000000 --- a/mig/routine.h +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ - -#ifndef _ROUTINE_H -#define _ROUTINE_H - -#include <sys/types.h> - -#include "boolean.h" -#include "type.h" - -/* base kind arg */ -#define akeNone (0) -#define akeNormal (1) /* a normal, user-defined argument */ -#define akeRequestPort (2) /* pointed at by rtRequestPort */ -#define akeWaitTime (3) /* pointed at by rtWaitTime */ -#define akeReplyPort (4) /* pointed at by rtReplyPort */ -#define akeMsgOption (5) /* pointed at by rtMsgOption */ -#define akeMsgSeqno (6) /* pointed at by rtMsgSeqno */ -#define akeRetCode (7) /* pointed at by rtRetCode/rtReturn */ -#define akeReturn (8) /* pointed at by rtReturn */ -#define akeCount (9) /* a count arg for argParent */ -#define akePoly (10) /* a poly arg for argParent */ -#define akeDealloc (11) /* a deallocate arg for argParent */ -#define akeServerCopy (12) /* a server-copy arg for argParent */ -#define akeCountInOut (13) /* a count-in-out arg */ - -#define akeBITS (0x0000003f) -#define akbRequest (0x00000040) /* has a msg_type in request */ -#define akbReply (0x00000080) /* has a msg_type in reply */ -#define akbUserArg (0x00000100) /* an arg on user-side */ -#define akbServerArg (0x00000200) /* an arg on server-side */ -#define akbSend (0x00000400) /* value carried in request */ -#define akbSendBody (0x00000800) /* value carried in request body */ -#define akbSendSnd (0x00001000) /* value stuffed into request */ -#define akbSendRcv (0x00002000) /* value grabbed from request */ -#define akbReturn (0x00004000) /* value carried in reply */ -#define akbReturnBody (0x00008000) /* value carried in reply body */ -#define akbReturnSnd (0x00010000) /* value stuffed into reply */ -#define akbReturnRcv (0x00020000) /* value grabbed from reply */ -#define akbReplyInit (0x00040000) /* reply msg-type must be init'ed */ -#define akbRequestQC (0x00080000) /* msg_type can be checked quickly */ -#define akbReplyQC (0x00100000) /* msg_type can be checked quickly */ -#define akbReplyCopy (0x00200000) /* copy reply value from request */ -#define akbVarNeeded (0x00400000) /* may need local var in server */ -#define akbDestroy (0x00800000) /* call destructor function */ -#define akbVariable (0x01000000) /* variable size inline data */ -#define akbIndefinite (0x02000000) /* variable size, inline or out */ -#define akbPointer (0x04000000) /* server gets a pointer to the - real buffer */ -/* be careful, there aren't many bits left */ - -typedef u_int arg_kind_t; - -/* - * akbRequest means msg_type/data fields are allocated in the request - * msg. akbReply means msg_type/data fields are allocated in the - * reply msg. These bits (with akbReplyInit, akbRequestQC, akbReplyQC) - * control msg structure declarations packing, and checking of - * mach_msg_type_t fields. - * - * akbUserArg means this argument is an argument to the user-side stub. - * akbServerArg means this argument is an argument to - * the server procedure called by the server-side stub. - * - * The akbSend* and akbReturn* bits control packing/extracting values - * in the request and reply messages. - * - * akbSend means the argument's value is carried in the request msg. - * akbSendBody implies akbSend; the value is carried in the msg body. - * akbSendSnd implies akbSend; the value is stuffed into the request. - * akbSendRcv implies akbSend; the value is pulled out of the request. - * - * akbReturn, akbReturnBody, akbReturnSnd, akbReturnRcv are defined - * similarly but apply to the reply message. - * - * User-side code generation (header.c, user.c) and associated code - * should use akbSendSnd and akbReturnRcv, but not akbSendRcv and - * akbReturnSnd. Server-side code generation (server.c) is reversed. - * Code generation should use the more specific akb{Send,Return}{Snd,Rcv} - * bits when possible, instead of akb{Send,Return}. - * - * Note that akRetCode and akReturn lack any Return bits, although - * there is a value in the msg. These guys are packed/unpacked - * with special code, unlike other arguments. - * - * akbReplyInit implies akbReply. It means the server-side stub - * should initialize the argument's msg_type field in the reply msg. - * Some special arguments (RetCode, Dummy, Tid) have their msg_type - * fields in the reply message initialized by the server demux - * function; these arguments have akbReply but not akbReplyInit. - * - * akbRequestQC implies akbRequest. If it's on, then the - * mach_msg_type_t value in the request message can be checked quickly - * (by casting to an int and checking with a single comparison). - * akbReplyQC has the analogous meaning with respect to akbReply. - * - * akbVariable means the argument has variable-sized inline data. - * It isn't currently used for code generation, but routine.c - * does use it internally. It is added in rtAugmentArgKind. - * - * akbReplyCopy and akbVarNeeded help control code generation in the - * server-side stub. The preferred method of handling data in the - * server-side stub avoids copying into/out-of local variables. In - * arguments get passed directly to the server proc from the request msg. - * Out arguments get stuffed directly into the reply msg by the server proc. - * For InOut arguments, the server proc gets the address of the data in - * the request msg, and the resulting data gets copied to the reply msg. - * Some arguments need a local variable in the server-side stub. The - * code extracts the data from the request msg into the variable, and - * stuff the reply msg from the variable. - * - * akbReplyCopy implies akbReply. It means the data should get copied - * from the request msg to the reply msg after the server proc is called. - * It is only used by akInOut. akTid doesn't need it because the tid - * data in the reply msg is initialized in the server demux function. - * - * akbVarNeeded means the argument needs a local variable in the - * server-side stub. It is added in rtAugmentArgKind and - * rtCheckVariable. An argument shouldn't have all three of - * akbReturnSnd, akbVarNeeded and akbReplyCopy, because this indicates - * the reply msg should be stuffed both ways. - * - * akbDestroy helps control code generation in the server-side stub. - * It means this argument has a destructor function which should be called. - * - * Header file generation (header.c) uses: - * akbUserArg - * - * User stub generation (user.c) uses: - * akbUserArg, akbRequest, akbReply, akbSendSnd, - * akbSendBody, akbReturnRcv, akbReplyQC - * - * Server stub generation (server.c) uses: - * akbServerArg, akbRequest, akbReply, akbSendRcv, akbReturnSnd, - * akbReplyInit, akbReplyCopy, akbVarNeeded, akbSendBody, akbRequestQC - * - * - * During code generation, the routine, argument, and type data structures - * are read-only. The code generation functions' output is their only - * side-effect. - * - * - * Style note: - * Code can use logical operators (|, &, ~) on akb values. - * ak values should be manipulated with the ak functions. - */ - -/* various useful combinations */ - -#define akbNone (0) -#define akbAll (~akbNone) -#define akbAllBits (~akeBITS) - -#define akbSendBits (akbSend|akbSendBody|akbSendSnd|akbSendRcv) -#define akbReturnBits (akbReturn|akbReturnBody|akbReturnSnd|akbReturnRcv) -#define akbSendReturnBits (akbSendBits|akbReturnBits) - -#define akNone akeNone - -#define akIn akAddFeature(akeNormal, \ - akbUserArg|akbServerArg|akbRequest|akbSendBits) - -#define akOut akAddFeature(akeNormal, \ - akbUserArg|akbServerArg|akbReply|akbReturnBits|akbReplyInit) - -#define akInOut akAddFeature(akeNormal, \ - akbUserArg|akbServerArg|akbRequest|akbReply| \ - akbSendBits|akbReturnBits|akbReplyInit|akbReplyCopy) - -#define akRequestPort akAddFeature(akeRequestPort, \ - akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv) - -#define akWaitTime akAddFeature(akeWaitTime, akbUserArg) - -#define akMsgOption akAddFeature(akeMsgOption, akbUserArg) - -#define akMsgSeqno akAddFeature(akeMsgSeqno, \ - akbServerArg|akbSend|akbSendRcv) - -#define akReplyPort akAddFeature(akeReplyPort, \ - akbUserArg|akbServerArg|akbSend|akbSendSnd|akbSendRcv) - -#define akUReplyPort akAddFeature(akeReplyPort, \ - akbUserArg|akbSend|akbSendSnd|akbSendRcv) - -#define akSReplyPort akAddFeature(akeReplyPort, \ - akbServerArg|akbSend|akbSendSnd|akbSendRcv) - -#define akRetCode akAddFeature(akeRetCode, akbReply) - -#define akReturn akAddFeature(akeReturn, \ - akbReply|akbReplyInit) - -#define akCount akAddFeature(akeCount, \ - akbUserArg|akbServerArg) - -#define akPoly akePoly - -#define akDealloc akAddFeature(akeDealloc, akbUserArg) - -#define akServerCopy akAddFeature(akeServerCopy, akbServerArg|akbSendRcv) - -#define akCountInOut akAddFeature(akeCountInOut, akbRequest|akbSendBits) - -#define akCheck(ak, bits) ((ak) & (bits)) -#define akCheckAll(ak, bits) (akCheck(ak, bits) == (bits)) -#define akAddFeature(ak, bits) ((ak)|(bits)) -#define akRemFeature(ak, bits) ((ak)&~(bits)) -#define akIdent(ak) ((ak) & akeBITS) - -/* - * The arguments to a routine/function are linked in left-to-right order. - * argName is used for error messages and pretty-printing, - * not code generation. Code generation shouldn't make any assumptions - * about the order of arguments, esp. count and poly arguments. - * (Unfortunately, code generation for inline variable-sized arguments - * does make such assumptions.) - * - * argVarName is the name used in generated code for function arguments - * and local variable names. argMsgField is the name used in generated - * code for the field in msgs where the argument's value lives. - * argTTName is the name used in generated code for msg-type fields and - * static variables used to initialize those fields. argPadName is the - * name used in generated code for a padding field in msgs. - * - * argFlags can be used to override the deallocate and longform bits - * in the argument's type. rtProcessArgFlags sets argDeallocate and - * argLongForm from it and the type. Code generation shouldn't use - * argFlags. - * - * argCount, argPoly, and argDealloc get to the implicit count, poly, - * and dealloc arguments associated with the argument; they should be - * used instead of argNext. In these implicit arguments, argParent is - * a pointer to the "real" arg. - * - * In count arguments, argMultiplier is a scaling factor applied to - * the count arg's value to get msg-type-number. It is equal to - * argParent->argType->itElement->itNumber - */ - -typedef struct argument -{ - /* if argKind == akReturn, then argName is name of the function */ - identifier_t argName; - struct argument *argNext; - - arg_kind_t argKind; - ipc_type_t *argType; - - const_string_t argVarName; /* local variable and argument names */ - const_string_t argMsgField; /* message field's name */ - const_string_t argTTName; /* name for msg_type fields, static vars */ - const_string_t argPadName; /* name for pad field in msg */ - - ipc_flags_t argFlags; - dealloc_t argDeallocate; /* overrides argType->itDeallocate */ - boolean_t argLongForm; /* overrides argType->itLongForm */ - boolean_t argServerCopy; - boolean_t argCountInOut; - - struct routine *argRoutine; /* routine we are part of */ - - struct argument *argCount; /* our count arg, if present */ - struct argument *argCInOut; /* our CountInOut arg, if present */ - struct argument *argPoly; /* our poly arg, if present */ - struct argument *argDealloc;/* our dealloc arg, if present */ - struct argument *argSCopy; /* our serverCopy arg, if present */ - struct argument *argParent; /* in a count or poly arg, the base arg */ - int argMultiplier; /* for Count argument: parent is a multiple - of a basic IPC type. Argument must be - multiplied by Multiplier to get IPC - number-of-elements. */ - - /* how variable/inline args precede this one, in request and reply */ - int argRequestPos; - int argReplyPos; - /* whether argument is by reference, on user and server side */ - boolean_t argByReferenceUser; - boolean_t argByReferenceServer; -} argument_t; - -/* - * The various routine kinds' peculiarities are abstracted by rtCheckRoutine - * into attributes like rtOneWay, rtProcedure, etc. These are what - * code generation should use. It is Bad Form for code generation to - * test rtKind. - */ - -typedef enum -{ - rkRoutine, - rkSimpleRoutine, - rkSimpleProcedure, - rkProcedure, - rkFunction, -} routine_kind_t; - -typedef struct routine -{ - identifier_t rtName; - routine_kind_t rtKind; - argument_t *rtArgs; - u_int rtNumber; /* used for making msg ids */ - - identifier_t rtUserName; /* user-visible name (UserPrefix + Name) */ - identifier_t rtServerName; /* server-side name (ServerPrefix + Name) */ - - /* rtErrorName is only used for Procs, SimpleProcs, & Functions */ - identifier_t rtErrorName; /* error-handler name */ - - boolean_t rtOneWay; /* SimpleProcedure or SimpleRoutine */ - boolean_t rtProcedure; /* Procedure or SimpleProcedure */ - boolean_t rtUseError; /* Procedure or Function */ - - boolean_t rtSimpleFixedRequest; /* fixed msg-simple value in request */ - boolean_t rtSimpleSendRequest; /* in any case, initial value */ - boolean_t rtSimpleCheckRequest; /* check msg-simple in request */ - boolean_t rtSimpleReceiveRequest; /* if so, the expected value */ - - boolean_t rtSimpleFixedReply; /* fixed msg-simple value in reply */ - boolean_t rtSimpleSendReply; /* in any case, initial value */ - boolean_t rtSimpleCheckReply; /* check msg-simple in reply */ - boolean_t rtSimpleReceiveReply; /* if so, the expected value */ - - u_int rtRequestSize; /* minimal size of a legal request msg */ - u_int rtReplySize; /* minimal size of a legal reply msg */ - - int rtNumRequestVar; /* number of variable/inline args in request */ - int rtNumReplyVar; /* number of variable/inline args in reply */ - - int rtMaxRequestPos; /* maximum of argRequestPos */ - int rtMaxReplyPos; /* maximum of argReplyPos */ - - boolean_t rtNoReplyArgs; /* if so, no reply message arguments beyond - what the server dispatch routine inserts */ - - /* distinguished arguments */ - argument_t *rtRequestPort; /* always non-NULL, defaults to first arg */ - argument_t *rtUReplyPort; /* always non-NULL, defaults to Mig-supplied */ - argument_t *rtSReplyPort; /* always non-NULL, defaults to Mig-supplied */ - argument_t *rtReturn; /* non-NULL unless rtProcedure */ - argument_t *rtServerReturn; /* NULL or rtReturn */ - argument_t *rtRetCode; /* always non-NULL */ - argument_t *rtWaitTime; /* if non-NULL, will use MACH_RCV_TIMEOUT */ - argument_t *rtMsgOption; /* always non-NULL, defaults to NONE */ - argument_t *rtMsgSeqno; /* if non-NULL, server gets passed seqno */ -} routine_t; - -#define rtNULL ((routine_t *) 0) -#define argNULL ((argument_t *) 0) - -extern u_int rtNumber; -/* rt->rtNumber will be initialized */ -extern routine_t *rtAlloc(void); -/* skip a number */ -extern void rtSkip(int); - -extern argument_t *argAlloc(void); - -extern boolean_t rtCheckMask(const argument_t *args, u_int mask); - -extern boolean_t rtCheckMaskFunction(const argument_t *args, u_int mask, - boolean_t (*func)(const argument_t *arg)); - -extern routine_t *rtMakeRoutine(identifier_t name, argument_t *args); -extern routine_t *rtMakeSimpleRoutine(identifier_t name, argument_t *args); -extern routine_t *rtMakeProcedure(identifier_t name, argument_t *args); -extern routine_t *rtMakeSimpleProcedure(identifier_t name, argument_t *args); -extern routine_t *rtMakeFunction(identifier_t name, argument_t *args, - ipc_type_t *type); - -extern void rtPrintRoutine(const routine_t *rt); -extern void rtCheckRoutine(routine_t *rt); - -extern const char *rtRoutineKindToStr(routine_kind_t rk); - -#endif /* _ROUTINE_H */ |