📄 msgpass.c
字号:
oldCore = MessageHandlerData(theEnv)->TopOfCore;
MessageHandlerData(theEnv)->TopOfCore = FindApplicableHandlers(theEnv,cls,mname);
if (MessageHandlerData(theEnv)->TopOfCore != NULL)
{
HANDLER_LINK *oldCurrent,*oldNext;
oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
oldNext = MessageHandlerData(theEnv)->NextInCore;
if (MessageHandlerData(theEnv)->TopOfCore->hnd->type == MAROUND)
{
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->TopOfCore;
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore->nxt;
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->WatchMessages)
WatchMessage(theEnv,WTRACE,BEGIN_TRACE);
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
#endif
if (CheckHandlerArgCount(theEnv))
{
#if PROFILING_FUNCTIONS
StartProfile(theEnv,&profileFrame,
&MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
ProfileFunctionData(theEnv)->ProfileConstructs);
#endif
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
result,UnboundHandlerErr);
#if PROFILING_FUNCTIONS
EndProfile(theEnv,&profileFrame);
#endif
}
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
if (MessageHandlerData(theEnv)->WatchMessages)
WatchMessage(theEnv,WTRACE,END_TRACE);
#endif
}
else
{
MessageHandlerData(theEnv)->CurrentCore = NULL;
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->TopOfCore;
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->WatchMessages)
WatchMessage(theEnv,WTRACE,BEGIN_TRACE);
#endif
CallHandlers(theEnv,result);
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->WatchMessages)
WatchMessage(theEnv,WTRACE,END_TRACE);
#endif
}
DestroyHandlerLinks(theEnv,MessageHandlerData(theEnv)->TopOfCore);
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
MessageHandlerData(theEnv)->NextInCore = oldNext;
}
MessageHandlerData(theEnv)->TopOfCore = oldCore;
ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
if (ins != NULL)
ins->busy--;
/* ==================================
Restore the original calling frame
================================== */
PopProcParameters(theEnv);
EvaluationData(theEnv)->CurrentEvaluationDepth--;
MessageHandlerData(theEnv)->CurrentMessageName = oldName;
PropagateReturnValue(theEnv,result);
PeriodicCleanup(theEnv,FALSE,TRUE);
SetExecutingConstruct(theEnv,oldce);
if (EvaluationData(theEnv)->EvaluationError)
{
result->type = SYMBOL;
result->value = EnvFalseSymbol(theEnv);
}
}
/*****************************************************************************
NAME : FindApplicableHandlers
DESCRIPTION : Given a message name, this routine forms the "core frame"
for the message : a list of all applicable class handlers.
An applicable class handler is one whose name matches
the message and whose class matches the instance.
The list is in the following order :
All around handlers (from most specific to most general)
All before handlers (from most specific to most general)
All primary handlers (from most specific to most general)
All after handlers (from most general to most specific)
INPUTS : 1) The class of the instance (or primitive) for the message
2) The message name
RETURNS : NULL if no applicable handlers or errors,
the list of handlers otherwise
SIDE EFFECTS : Links are allocated for the list
NOTES : The instance is the first thing on the ProcParamArray
The number of arguments is in ProcParamArraySize
*****************************************************************************/
static HANDLER_LINK *FindApplicableHandlers(
void *theEnv,
DEFCLASS *cls,
SYMBOL_HN *mname)
{
register int i;
HANDLER_LINK *tops[4],*bots[4];
for (i = MAROUND ; i <= MAFTER ; i++)
tops[i] = bots[i] = NULL;
for (i = 0 ; i < cls->allSuperclasses.classCount ; i++)
FindApplicableOfName(theEnv,cls->allSuperclasses.classArray[i],tops,bots,mname);
return(JoinHandlerLinks(theEnv,tops,bots,mname));
}
/***************************************************************
NAME : CallHandlers
DESCRIPTION : Moves though the current message frame
for a send-message as follows :
Call all before handlers and ignore their
return values.
Call the first primary handler and
ignore the rest. The return value
of the handler frame is this message's value.
Call all after handlers and ignore their
return values.
INPUTS : Caller's buffer for the return value of
the message
RETURNS : Nothing useful
SIDE EFFECTS : The handlers are evaluated.
NOTES : IMPORTANT : The global NextInCore should be
pointing to the first handler to be executed.
***************************************************************/
static void CallHandlers(
void *theEnv,
DATA_OBJECT *result)
{
#if IBM_TBC
HANDLER_LINK *oldCurrent,*oldNext; /* prevents warning */
#else
HANDLER_LINK *oldCurrent = NULL,*oldNext = NULL; /* prevents warning */
#endif
DATA_OBJECT temp;
#if PROFILING_FUNCTIONS
struct profileFrameInfo profileFrame;
#endif
if (EvaluationData(theEnv)->HaltExecution)
return;
oldCurrent = MessageHandlerData(theEnv)->CurrentCore;
oldNext = MessageHandlerData(theEnv)->NextInCore;
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MBEFORE)
{
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
#endif
if (CheckHandlerArgCount(theEnv))
{
#if PROFILING_FUNCTIONS
StartProfile(theEnv,&profileFrame,
&MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
ProfileFunctionData(theEnv)->ProfileConstructs);
#endif
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
&temp,UnboundHandlerErr);
#if PROFILING_FUNCTIONS
EndProfile(theEnv,&profileFrame);
#endif
}
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
#endif
ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
{
MessageHandlerData(theEnv)->NextInCore = oldNext;
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
return;
}
}
if (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
{
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
#endif
if (CheckHandlerArgCount(theEnv))
{
#if PROFILING_FUNCTIONS
StartProfile(theEnv,&profileFrame,
&MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
ProfileFunctionData(theEnv)->ProfileConstructs);
#endif
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
result,UnboundHandlerErr);
#if PROFILING_FUNCTIONS
EndProfile(theEnv,&profileFrame);
#endif
}
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
#endif
ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
{
MessageHandlerData(theEnv)->NextInCore = oldNext;
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
return;
}
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MPRIMARY)
{
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
if (MessageHandlerData(theEnv)->NextInCore == NULL)
{
MessageHandlerData(theEnv)->NextInCore = oldNext;
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
return;
}
}
}
while (MessageHandlerData(theEnv)->NextInCore->hnd->type == MAFTER)
{
MessageHandlerData(theEnv)->CurrentCore = MessageHandlerData(theEnv)->NextInCore;
MessageHandlerData(theEnv)->NextInCore = MessageHandlerData(theEnv)->NextInCore->nxt;
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,BEGIN_TRACE);
#endif
if (CheckHandlerArgCount(theEnv))
{
#if PROFILING_FUNCTIONS
StartProfile(theEnv,&profileFrame,
&MessageHandlerData(theEnv)->CurrentCore->hnd->usrData,
ProfileFunctionData(theEnv)->ProfileConstructs);
#endif
EvaluateProcActions(theEnv,MessageHandlerData(theEnv)->CurrentCore->hnd->cls->header.whichModule->theModule,
MessageHandlerData(theEnv)->CurrentCore->hnd->actions,
MessageHandlerData(theEnv)->CurrentCore->hnd->localVarCount,
&temp,UnboundHandlerErr);
#if PROFILING_FUNCTIONS
EndProfile(theEnv,&profileFrame);
#endif
}
#if DEBUGGING_FUNCTIONS
if (MessageHandlerData(theEnv)->CurrentCore->hnd->trace)
WatchHandler(theEnv,WTRACE,MessageHandlerData(theEnv)->CurrentCore,END_TRACE);
#endif
ProcedureFunctionData(theEnv)->ReturnFlag = FALSE;
if ((MessageHandlerData(theEnv)->NextInCore == NULL) || EvaluationData(theEnv)->HaltExecution)
{
MessageHandlerData(theEnv)->NextInCore = oldNext;
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
return;
}
}
MessageHandlerData(theEnv)->NextInCore = oldNext;
MessageHandlerData(theEnv)->CurrentCore = oldCurrent;
}
/********************************************************
NAME : EarlySlotBindError
DESCRIPTION : Prints out an error message when
a message-handler from a superclass
which contains a static-bind
slot access is not valid for the
currently active instance (i.e.
the instance is not using the
superclass's slot)
INPUTS : 1) The currently active instance
2) The defclass holding the invalid slot
3) The canonical id of the slot
RETURNS : Nothing useful
SIDE EFFECTS : Error message printed
NOTES : None
********************************************************/
static void EarlySlotBindError(
void *theEnv,
INSTANCE_TYPE *theInstance,
DEFCLASS *theDefclass,
unsigned slotID)
{
SLOT_DESC *sd;
sd = theDefclass->instanceTemplate[theDefclass->slotNameMap[slotID] - 1];
PrintErrorID(theEnv,"MSGPASS",3,FALSE);
EnvPrintRouter(theEnv,WERROR,"Static reference to slot ");
EnvPrintRouter(theEnv,WERROR,ValueToString(sd->slotName->name));
EnvPrintRouter(theEnv,WERROR," of class ");
PrintClassName(theEnv,WERROR,theDefclass,FALSE);
EnvPrintRouter(theEnv,WERROR," does not apply to ");
PrintInstanceNameAndClass(theEnv,WERROR,theInstance,TRUE);
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -