An inTransPayload function maps payloads to objects, like an inTrans function maps from port names to objects. Generate code in the server routine to optimize lookups to the receiver of the message.
Additionally, if no intran function is provided, but an intranpayload function is, it is expected to map from payloads to port names. This is used to preserve the semantics in case the server routine expects a port name. * server.c (WriteExtractArgValue): If a payload-aware intrans function has been specified, use it to get a reference to the receiving object. * routine.c (rtAugmentArgKind): Force the use of a local variable if a payload-aware translate-in function is defined. --- routine.c | 4 +++- server.c | 39 +++++++++++++++++++++++++++++++++++---- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/routine.c b/routine.c index 94e2b4c..ddf5770 100644 --- a/routine.c +++ b/routine.c @@ -540,6 +540,7 @@ rtAugmentArgKind(argument_t *arg) * 6) This is a dealloc arg, being returned. The name can't be * stored directly into the msg_type, because the msg-type * field is a bit-field. + * 7) There is a payload-aware translate-in function defined. */ if (((it->itOutTrans != strNULL) && @@ -555,7 +556,8 @@ rtAugmentArgKind(argument_t *arg) ((akIdent(arg->argKind) == akePoly) && akCheck(arg->argKind, akbReturnSnd)) || ((akIdent(arg->argKind) == akeDealloc) && - akCheck(arg->argKind, akbReturnSnd))) + akCheck(arg->argKind, akbReturnSnd)) || + (it->itInTransPayload != strNULL)) { arg->argKind = akRemFeature(arg->argKind, akbReplyCopy); arg->argKind = akAddFeature(arg->argKind, akbVarNeeded); diff --git a/server.c b/server.c index 8496da7..e6621cf 100644 --- a/server.c +++ b/server.c @@ -580,14 +580,45 @@ static void WriteExtractArgValue(FILE *file, const argument_t *arg) { const ipc_type_t *it = arg->argType; + boolean_t have_payload; if (arg->argMultiplier > 1) WriteCopyType(file, it, "%s", "/* %s */ %s / %d", arg->argVarName, InArgMsgField(arg), arg->argMultiplier); - else if (it->itInTrans != strNULL) - WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", - arg->argVarName, it->itInTrans, InArgMsgField(arg)); - else + else if ((have_payload = (it->itInTransPayload != strNULL && + strcmp(arg->argMsgField, "Head.msgh_request_port") == 0)) || + it->itInTrans != strNULL) { + + if (have_payload) { + argument_t argPayload = *arg; + argPayload.argMsgField = "Head.msgh_bits"; + fprintf(file, + "\tif (MACH_MSGH_BITS_LOCAL (%s) == " + "MACH_MSG_TYPE_PROTECTED_PAYLOAD)\n" + "\t", InArgMsgField(&argPayload)); + + argPayload.argMsgField = "Head.msgh_protected_payload"; + WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", + arg->argVarName, it->itInTransPayload, + InArgMsgField(&argPayload)); + + fprintf(file, + "\telse\n" + "\t"); + + if (it->itInTrans == strNULL) + fprintf(file, "\t%s = %s;", + arg->argVarName, InArgMsgField(arg)); + else + WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", + arg->argVarName, it->itInTrans, + InArgMsgField(arg)); + } else { + WriteCopyType(file, it, "%s", "/* %s */ %s(%s)", + arg->argVarName, it->itInTrans, + InArgMsgField(arg)); + } + } else WriteCopyType(file, it, "%s", "/* %s */ %s", arg->argVarName, InArgMsgField(arg)); fprintf(file, "\n"); -- 1.7.10.4