📄 msgpass.c
字号:
DESCRIPTION : Access function for handling the statically-bound direct slot bindings in message-handlers INPUTS : 1) The bitmap expression 2) A data object buffer RETURNS : TRUE if OK, FALSE on errors SIDE EFFECTS : Data object buffer gets symbol TRUE and slot is set. On errors, buffer gets symbol FALSE, EvaluationError is set and error messages are printed NOTES : It is possible for a handler (attached to a superclass of the currently active instance) containing these static references to be called for an instance which does not contain the slots (e.g., an instance of a subclass where the original slot was no-inherit or the subclass overrode the original slot) ***************************************************/globle intBool HandlerSlotPutFunction( void *theEnv, void *theValue, DATA_OBJECT *theResult) { HANDLER_SLOT_REFERENCE *theReference; DEFCLASS *theDefclass; INSTANCE_TYPE *theInstance; INSTANCE_SLOT *sp; unsigned instanceSlotIndex; DATA_OBJECT theSetVal; theReference = (HANDLER_SLOT_REFERENCE *) ValueToBitMap(theValue); theInstance = (INSTANCE_TYPE *) ProceduralPrimitiveData(theEnv)->ProcParamArray[0].value; theDefclass = DefclassData(theEnv)->ClassIDMap[theReference->classID]; if (theInstance->garbage) { StaleInstanceAddress(theEnv,"for slot put",0); theResult->type = SYMBOL; theResult->value = EnvFalseSymbol(theEnv); SetEvaluationError(theEnv,TRUE); return(FALSE); } if (theInstance->cls == theDefclass) { instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID]; sp = theInstance->slotAddresses[instanceSlotIndex - 1]; } else { if (theReference->slotID > theInstance->cls->maxSlotNameID) goto HandlerPutError; instanceSlotIndex = theInstance->cls->slotNameMap[theReference->slotID]; if (instanceSlotIndex == 0) goto HandlerPutError; instanceSlotIndex--; sp = theInstance->slotAddresses[instanceSlotIndex]; if (sp->desc->cls != theDefclass) goto HandlerPutError; } /* ======================================================= The slot has already been verified not to be read-only. However, if it is initialize-only, we need to make sure that we are initializing the instance (something we could not verify at parse-time) ======================================================= */ if (sp->desc->initializeOnly && (!theInstance->initializeInProgress)) { SlotAccessViolationError(theEnv,ValueToString(sp->desc->slotName->name), TRUE,(void *) theInstance); goto HandlerPutError2; } /* ====================================== No arguments means to use the special NoParamValue to reset the slot to its default value ====================================== */ if (GetFirstArgument()) { if (EvaluateAndStoreInDataObject(theEnv,(int) sp->desc->multiple, GetFirstArgument(),&theSetVal,TRUE) == FALSE) goto HandlerPutError2; } else { SetDOBegin(theSetVal,1); SetDOEnd(theSetVal,0); SetType(theSetVal,MULTIFIELD); SetValue(theSetVal,ProceduralPrimitiveData(theEnv)->NoParamValue); } if (PutSlotValue(theEnv,theInstance,sp,&theSetVal,theResult,NULL) == FALSE) goto HandlerPutError2; return(TRUE);HandlerPutError: EarlySlotBindError(theEnv,theInstance,theDefclass,theReference->slotID);HandlerPutError2: theResult->type = SYMBOL; theResult->value = EnvFalseSymbol(theEnv); SetEvaluationError(theEnv,TRUE); return(FALSE); }/***************************************************** NAME : DynamicHandlerGetSlot DESCRIPTION : Directly references a slot's value (uses dynamic binding to lookup slot) INPUTS : The caller's result buffer RETURNS : Nothing useful SIDE EFFECTS : Caller's result buffer set NOTES : H/L Syntax: (get <slot>) *****************************************************/globle void DynamicHandlerGetSlot( void *theEnv, DATA_OBJECT *result) { INSTANCE_SLOT *sp; INSTANCE_TYPE *ins; DATA_OBJECT temp; result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv); if (CheckCurrentMessage(theEnv,"dynamic-get",TRUE) == FALSE) return; EvaluateExpression(theEnv,GetFirstArgument(),&temp); if (temp.type != SYMBOL) { ExpectedTypeError1(theEnv,"dynamic-get",1,"symbol"); SetEvaluationError(theEnv,TRUE); return; } ins = GetActiveInstance(theEnv); sp = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) temp.value); if (sp == NULL) { SlotExistError(theEnv,ValueToString(temp.value),"dynamic-get"); return; } if ((sp->desc->publicVisibility == 0) && (MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls)) { SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls); SetEvaluationError(theEnv,TRUE); return; } result->type = (unsigned short) sp->type; result->value = sp->value; if (sp->type == MULTIFIELD) { result->begin = 0; SetpDOEnd(result,GetInstanceSlotLength(sp)); } }/*********************************************************** NAME : DynamicHandlerPutSlot DESCRIPTION : Directly puts a slot's value (uses dynamic binding to lookup slot) INPUTS : Data obejct buffer for holding slot value RETURNS : Nothing useful SIDE EFFECTS : Slot modified - and caller's buffer set to value (or symbol FALSE on errors) NOTES : H/L Syntax: (put <slot> <value>*) ***********************************************************/globle void DynamicHandlerPutSlot( void *theEnv, DATA_OBJECT *theResult) { INSTANCE_SLOT *sp; INSTANCE_TYPE *ins; DATA_OBJECT temp; theResult->type = SYMBOL; theResult->value = EnvFalseSymbol(theEnv); if (CheckCurrentMessage(theEnv,"dynamic-put",TRUE) == FALSE) return; EvaluateExpression(theEnv,GetFirstArgument(),&temp); if (temp.type != SYMBOL) { ExpectedTypeError1(theEnv,"dynamic-put",1,"symbol"); SetEvaluationError(theEnv,TRUE); return; } ins = GetActiveInstance(theEnv); sp = FindInstanceSlot(theEnv,ins,(SYMBOL_HN *) temp.value); if (sp == NULL) { SlotExistError(theEnv,ValueToString(temp.value),"dynamic-put"); return; } if ((sp->desc->noWrite == 0) ? FALSE : ((sp->desc->initializeOnly == 0) || (!ins->initializeInProgress))) { SlotAccessViolationError(theEnv,ValueToString(sp->desc->slotName->name), TRUE,(void *) ins); SetEvaluationError(theEnv,TRUE); return; } if ((sp->desc->publicVisibility == 0) && (MessageHandlerData(theEnv)->CurrentCore->hnd->cls != sp->desc->cls)) { SlotVisibilityViolationError(theEnv,sp->desc,MessageHandlerData(theEnv)->CurrentCore->hnd->cls); SetEvaluationError(theEnv,TRUE); return; } if (GetFirstArgument()->nextArg) { if (EvaluateAndStoreInDataObject(theEnv,(int) sp->desc->multiple, GetFirstArgument()->nextArg,&temp,TRUE) == FALSE) return; } else { SetpDOBegin(&temp,1); SetpDOEnd(&temp,0); SetpType(&temp,MULTIFIELD); SetpValue(&temp,ProceduralPrimitiveData(theEnv)->NoParamValue); } PutSlotValue(theEnv,ins,sp,&temp,theResult,NULL); }/* ========================================= ***************************************** INTERNALLY VISIBLE FUNCTIONS ========================================= ***************************************** *//***************************************************** NAME : PerformMessage DESCRIPTION : Calls core framework for a message INPUTS : 1) Caller's result buffer 2) Message argument expressions (including implicit object) 3) Message name RETURNS : Nothing useful SIDE EFFECTS : Any side-effects of message execution and caller's result buffer set NOTES : None *****************************************************/static void PerformMessage( void *theEnv, DATA_OBJECT *result, EXPRESSION *args, SYMBOL_HN *mname) { int oldce; /* HANDLER_LINK *oldCore; */ DEFCLASS *cls = NULL; INSTANCE_TYPE *ins = NULL; SYMBOL_HN *oldName;#if PROFILING_FUNCTIONS struct profileFrameInfo profileFrame;#endif result->type = SYMBOL; result->value = EnvFalseSymbol(theEnv); EvaluationData(theEnv)->EvaluationError = FALSE; if (EvaluationData(theEnv)->HaltExecution) return; oldce = ExecutingConstruct(theEnv); SetExecutingConstruct(theEnv,TRUE); oldName = MessageHandlerData(theEnv)->CurrentMessageName; MessageHandlerData(theEnv)->CurrentMessageName = mname; EvaluationData(theEnv)->CurrentEvaluationDepth++; PushProcParameters(theEnv,args,CountArguments(args), ValueToString(MessageHandlerData(theEnv)->CurrentMessageName),"message", UnboundHandlerErr); if (EvaluationData(theEnv)->EvaluationError) { EvaluationData(theEnv)->CurrentEvaluationDepth--; MessageHandlerData(theEnv)->CurrentMessageName = oldName; PeriodicCleanup(theEnv,FALSE,TRUE); SetExecutingConstruct(theEnv,oldce); return; } if (ProceduralPrimitiveData(theEnv)->ProcParamArray->type == INSTANCE_ADDRESS) { ins = (INSTANCE_TYPE *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value; if (ins->garbage == 1) { StaleInstanceAddress(theEnv,"send",0); SetEvaluationError(theEnv,TRUE); } else if (DefclassInScope(theEnv,ins->cls,(struct defmodule *) EnvGetCurrentModule(theEnv)) == FALSE) NoInstanceError(theEnv,ValueToString(ins->name),"send"); else { cls = ins->cls; ins->busy++; } } else if (ProceduralPrimitiveData(theEnv)->ProcParamArray->type == INSTANCE_NAME) { ins = FindInstanceBySymbol(theEnv,(SYMBOL_HN *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value); if (ins == NULL) { PrintErrorID(theEnv,"MSGPASS",2,FALSE); EnvPrintRouter(theEnv,WERROR,"No such instance "); EnvPrintRouter(theEnv,WERROR,ValueToString((SYMBOL_HN *) ProceduralPrimitiveData(theEnv)->ProcParamArray->value)); EnvPrintRouter(theEnv,WERROR," in function send.\n"); SetEvaluationError(theEnv,TRUE); } else { ProceduralPrimitiveData(theEnv)->ProcParamArray->value = (void *) ins; ProceduralPrimitiveData(theEnv)->ProcParamArray->type = INSTANCE_ADDRESS; cls = ins->cls; ins->busy++; } } else if ((cls = DefclassData(theEnv)->PrimitiveClassMap[ProceduralPrimitiveData(theEnv)->ProcParamArray->type]) == NULL) { SystemError(theEnv,"MSGPASS",1); EnvExitRouter(theEnv,EXIT_FAILURE); } if (EvaluationData(theEnv)->EvaluationError) { PopProcParameters(theEnv); EvaluationData(theEnv)->CurrentEvaluationDepth--; MessageHandlerData(theEnv)->CurrentMessageName = oldName; PeriodicCleanup(theEnv,FALSE,TRUE); SetExecutingConstruct(theEnv,oldce); return; } /* oldCore = MessageHandlerData(theEnv)->TopOfCore; */ if (MessageHandlerData(theEnv)->TopOfCore != NULL) { MessageHandlerData(theEnv)->TopOfCore->nxtInStack = MessageHandlerData(theEnv)->OldCore; } MessageHandlerData(theEnv)->OldCore = MessageHandlerData(theEnv)->TopOfCore;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -