?? classpsr.c
字號(hào):
/******************************************************* NAME : BuildSubclassLinks DESCRIPTION : Follows the list of superclasses for a class and puts the class in each of the superclasses' subclass list. INPUTS : The address of the class RETURNS : Nothing useful SIDE EFFECTS : The subclass lists for every superclass are modified. NOTES : Assumes the superclass list is formed. *******************************************************/static void BuildSubclassLinks( void *theEnv, DEFCLASS *cls) { long i; for (i = 0 ; i < cls->directSuperclasses.classCount ; i++) AddClassLink(theEnv,&cls->directSuperclasses.classArray[i]->directSubclasses,cls,-1); }/********************************************************** NAME : FormInstanceTemplate DESCRIPTION : Forms a contiguous array of instance slots for use in creating instances later Also used in determining instance slot indices a priori during handler defns INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Contiguous array of instance slots formed NOTES : None **********************************************************/static void FormInstanceTemplate( void *theEnv, DEFCLASS *cls) { TEMP_SLOT_LINK *islots = NULL,*stmp; short scnt = 0; long i; /* ======================== Get direct class's slots ======================== */ islots = MergeSlots(theEnv,islots,cls,&scnt,DIRECT); /* =================================================================== Get all inherited slots - a more specific slot takes precedence over more general, i.e. the first class in the precedence list with a particular slot gets to specify its default value =================================================================== */ for (i = 1 ; i < cls->allSuperclasses.classCount ; i++) islots = MergeSlots(theEnv,islots,cls->allSuperclasses.classArray[i],&scnt,INHERIT); /* =================================================== Allocate a contiguous array to store all the slots. =================================================== */ cls->instanceSlotCount = scnt; cls->localInstanceSlotCount = 0; if (scnt > 0) cls->instanceTemplate = (SLOT_DESC **) gm2(theEnv,(scnt * sizeof(SLOT_DESC *))); for (i = 0 ; i < scnt ; i++) { stmp = islots; islots = islots->nxt; cls->instanceTemplate[i] = stmp->desc; if (stmp->desc->shared == 0) cls->localInstanceSlotCount++; rtn_struct(theEnv,tempSlotLink,stmp); } }/********************************************************** NAME : FormSlotNameMap DESCRIPTION : Forms a mapping of the slot name ids into the instance template. Given the slot name id, this map provides a much faster lookup of a slot. The id is stored statically in object patterns and can be looked up via a hash table at runtime as well. INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Contiguous array of integers formed The position in the array corresponding to a slot name id holds an the index into the instance template array holding the slot The max slot name id for the class is also stored to make deletion of the slots easier NOTES : Assumes the instance template has already been formed **********************************************************/static void FormSlotNameMap( void *theEnv, DEFCLASS *cls) { long i; cls->maxSlotNameID = 0; cls->slotNameMap = NULL; if (cls->instanceSlotCount == 0) return; for (i = 0 ; i < cls->instanceSlotCount ; i++) if (cls->instanceTemplate[i]->slotName->id > cls->maxSlotNameID) cls->maxSlotNameID = cls->instanceTemplate[i]->slotName->id; cls->slotNameMap = (unsigned *) gm2(theEnv,(sizeof(unsigned) * (cls->maxSlotNameID + 1))); for (i = 0 ; i <= cls->maxSlotNameID ; i++) cls->slotNameMap[i] = 0; for (i = 0 ; i < cls->instanceSlotCount ; i++) cls->slotNameMap[cls->instanceTemplate[i]->slotName->id] = i + 1; }/******************************************************************** NAME : MergeSlots DESCRIPTION : Adds non-duplicate slots to list and increments slot count for the class instance template INPUTS : 1) The old slot list 2) The address of class containing new slots 3) Caller's buffer for # of slots 4) A flag indicating whether the new list of slots is from the direct parent-class or not. RETURNS : The address of the new expanded list, or NULL for an empty list SIDE EFFECTS : The list is expanded Caller's slot count is adjusted. NOTES : Lists are assumed to contain no duplicates *******************************************************************/static TEMP_SLOT_LINK *MergeSlots( void *theEnv, TEMP_SLOT_LINK *old, DEFCLASS *cls, short *scnt, int src) { TEMP_SLOT_LINK *cur,*tmp; register int i; SLOT_DESC *newSlot; /* ====================================== Process the slots in reverse order since we are pushing them onto a stack ====================================== */ for (i = (int) (cls->slotCount - 1) ; i >= 0 ; i--) { newSlot = &cls->slots[i]; /* ========================================== A class can prevent it slots from being propagated to all but its direct instances ========================================== */ if ((newSlot->noInherit == 0) ? TRUE : (src == DIRECT)) { cur = old; while ((cur != NULL) ? (newSlot->slotName != cur->desc->slotName) : FALSE) cur = cur->nxt; if (cur == NULL) { tmp = get_struct(theEnv,tempSlotLink); tmp->desc = newSlot; tmp->nxt = old; old = tmp; (*scnt)++; } } } return(old); }/*********************************************************************** NAME : PackSlots DESCRIPTION : Groups class-slots into a contiguous array "slots" field points to array "slotCount" field set INPUTS : 1) The class 2) The list of slots RETURNS : Nothing useful SIDE EFFECTS : Temporary list deallocated, contiguous array allocated, and nxt pointers linked Class pointer set for slots NOTES : Assumes class->slotCount == 0 && class->slots == NULL ***********************************************************************/static void PackSlots( void *theEnv, DEFCLASS *cls, TEMP_SLOT_LINK *slots) { TEMP_SLOT_LINK *stmp,*sprv; long i; stmp = slots; while (stmp != NULL) { stmp->desc->cls = cls; cls->slotCount++; stmp = stmp->nxt; } cls->slots = (SLOT_DESC *) gm2(theEnv,(sizeof(SLOT_DESC) * cls->slotCount)); stmp = slots; for (i = 0 ; i < cls->slotCount ; i++) { sprv = stmp; stmp = stmp->nxt; GenCopyMemory(SLOT_DESC,1,&(cls->slots[i]),sprv->desc); cls->slots[i].sharedValue.desc = &(cls->slots[i]); cls->slots[i].sharedValue.value = NULL; rtn_struct(theEnv,slotDescriptor,sprv->desc); rtn_struct(theEnv,tempSlotLink,sprv); } }#if DEFMODULE_CONSTRUCT/******************************************************** NAME : CreateClassScopeMap DESCRIPTION : Creates a bitmap where each bit position corresponds to a module id. If the bit is set, the class is in scope for that module, otherwise it is not. INPUTS : The class RETURNS : Nothing useful SIDE EFFECTS : Scope bitmap created and attached NOTES : Uses FindImportedConstruct() ********************************************************/static void CreateClassScopeMap( void *theEnv, DEFCLASS *theDefclass) { unsigned scopeMapSize; char *scopeMap; char *className; struct defmodule *matchModule, *theModule; int moduleID,count; className = ValueToString(theDefclass->header.name); matchModule = theDefclass->header.whichModule->theModule; scopeMapSize = (sizeof(char) * ((GetNumberOfDefmodules(theEnv) / BITS_PER_BYTE) + 1)); scopeMap = (char *) gm2(theEnv,scopeMapSize); ClearBitString((void *) scopeMap,scopeMapSize); SaveCurrentModule(theEnv); for (theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,NULL) ; theModule != NULL ; theModule = (struct defmodule *) EnvGetNextDefmodule(theEnv,(void *) theModule)) { EnvSetCurrentModule(theEnv,(void *) theModule); moduleID = (int) theModule->bsaveID; if (FindImportedConstruct(theEnv,"defclass",matchModule, className,&count,TRUE,NULL) != NULL) SetBitMap(scopeMap,moduleID); } RestoreCurrentModule(theEnv); theDefclass->scopeMap = (BITMAP_HN *) AddBitMap(theEnv,scopeMap,scopeMapSize); IncrementBitMapCount(theDefclass->scopeMap); rm(theEnv,(void *) scopeMap,scopeMapSize); }#endif/***************************************************************************** NAME : CreatePublicSlotMessageHandlers DESCRIPTION : Creates a get-<slot-name> and put-<slot-name> handler for every public slot in a class. The syntax of the message-handlers created are: (defmessage-handler <class> get-<slot-name> primary () ?self:<slot-name>) For single-field slots: (defmessage-handler <class> put-<slot-name> primary (?value) (bind ?self:<slot-name> ?value)) For multifield slots: (defmessage-handler <class> put-<slot-name> primary ($?value) (bind ?self:<slot-name> ?value)) INPUTS : The defclass RETURNS : Nothing useful SIDE EFFECTS : Message-handlers created NOTES : None ******************************************************************************/static void CreatePublicSlotMessageHandlers( void *theEnv, DEFCLASS *theDefclass) { long i; register SLOT_DESC *sd; for (i = 0 ; i < theDefclass->slotCount ; i++) { sd = &theDefclass->slots[i]; CreateGetAndPutHandlers(theEnv,sd); } for (i = 0 ; i < theDefclass->handlerCount ; i++) theDefclass->handlers[i].system = TRUE; }#endif
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -