Index: generic/nsfCmdDefinitions.c =================================================================== diff -u -r760d5e6aa44c07331fea3c109385c309d906779c -rc01b411cdc631fd8e3eea9bf8fea985837a2b4b3 --- generic/nsfCmdDefinitions.c (.../nsfCmdDefinitions.c) (revision 760d5e6aa44c07331fea3c109385c309d906779c) +++ generic/nsfCmdDefinitions.c (.../nsfCmdDefinitions.c) (revision c01b411cdc631fd8e3eea9bf8fea985837a2b4b3) @@ -1,10 +1,11 @@ /* * nsfCmdDefinitions.c -- * - * Provide API for registering method definitions - * and obtaining this data for introspection + * Provide an API for registering method definitions + * and obtaining these meta-data for introspection. * * Copyright (C) 2014-2016 Gustaf Neumann + * Copyright (C) 2016 Stefan Sobernig * * Vienna University of Economics and Business * Institute of Information Systems and New Media @@ -43,156 +44,11 @@ static int Register(Tcl_Interp *interp, Nsf_methodDefinition *methodDefinition); - /* - * Defintions for HashType cmdPtr. - * - * Background: since it is not guaranteed that sizeof(function pointer) == - * sizeof(data pointer) (or sizeof(function pointer) <= sizeof(data pointer)), - * passing function pointers via data pointers - which is the default tcl hash - * types do - is dangerous. So we define our own type that allows to hash on - * function pointers safely. - * - */ -static unsigned int CmdPtrKey(Tcl_HashTable *tablePtr, VOID *keyPtr); -static int CompareCmdPtrKeys(VOID *keyPtr, Tcl_HashEntry *hPtr); -static Tcl_HashEntry *AllocCmdPtrEntry(Tcl_HashTable *tablePtr, VOID *keyPtr); - -typedef struct cmdPtrEntry_t { - Tcl_ObjCmdProc *proc; -} cmdPtrEntry_t; - -static Tcl_HashKeyType cmdPtrHashKeyType = { - 1, /* version*/ - 0, /* flags */ - CmdPtrKey, /* hashKeyProc*/ - CompareCmdPtrKeys, /* compareKeysProc */ - AllocCmdPtrEntry, /* allocEntryProc */ - NULL, /* freeEntryProc */ -}; - -/* *---------------------------------------------------------------------- - * - * CmdPtrKey -- - * - * Compute a unsigned int hash value from a function pointer. - * - * Results: - * Hash value. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static unsigned int -CmdPtrKey( - Tcl_HashTable *tablePtr, /* Hash table. */ - VOID *keyPtr) /* Key from which to compute hash value. */ -{ - cmdPtrEntry_t *cmdEntryPtr = (cmdPtrEntry_t *)keyPtr; - Tcl_ObjCmdProc *value = cmdEntryPtr->proc; - - //fprintf(stderr, "=== hash from %p = %u // 0x%x\n", (void *)value, PTR2UINT(value), PTR2UINT(value)); - /* - * This is a very simple approach for obtaining a hash value. Maybe one - * needs a more sophisticated approach with wierd endians machines. - */ - return PTR2UINT(value); - - /* - as a reference: tcl's string hash functions - - register unsigned int result; - register int c; - result = 0; - - for (c=*string++ ; c ; c=*string++) { - result += (result<<3) + c; - } - return result; - */ -} - -/* - *---------------------------------------------------------------------- - * - * CompareCmdPtrKeys -- - * - * Compares two cmd ptr keys. - * - * Results: - * The return value is 0 if they are different and 1 if they are the - * same. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -CompareCmdPtrKeys( - VOID *keyPtr, /* New key to compare. */ - Tcl_HashEntry *hPtr) /* Existing key to compare. */ -{ - cmdPtrEntry_t *cmdEntryPtr = (cmdPtrEntry_t *)keyPtr; - Tcl_ObjCmdProc *existingValue; - - memcpy(&existingValue, &hPtr->key.oneWordValue, sizeof(Tcl_ObjCmdProc *)); - - //fprintf(stderr, "=== compare new %p existing %p\n", (void *)cmdPtr->proc, (void *)existingValue); - - return cmdEntryPtr->proc == existingValue; -} - -/* - *---------------------------------------------------------------------- - * - * AllocCmdPtrEntry -- - * - * Allocate space for a Tcl_HashEntry containing the cmd ptr - * - * Results: - * The return value is a pointer to the created entry. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ -static Tcl_HashEntry * -AllocCmdPtrEntry( - Tcl_HashTable *tablePtr, /* Hash table. */ - VOID *keyPtr) /* Key to store in the hash table entry. */ -{ - cmdPtrEntry_t *cmdEntryPtr = (cmdPtrEntry_t *)keyPtr; - Tcl_HashEntry *hPtr; - unsigned int size; - Tcl_ObjCmdProc *value = cmdEntryPtr->proc; - - size = sizeof(Tcl_HashEntry) + (sizeof(Tcl_ObjCmdProc *)) - sizeof(hPtr->key); - if (size < sizeof(Tcl_HashEntry)) { - size = sizeof(Tcl_HashEntry); - } - //fprintf(stderr, "=== alloc entry %p\n", (void *)value); - hPtr = (Tcl_HashEntry *) ckalloc(size); - - //fprintf(stderr, "=== trying to copy %ld bytes from %p to %p\n", sizeof(Tcl_ObjCmdProc *), (void *)value, &hPtr->key.oneWordValue); - memcpy(&hPtr->key.oneWordValue, &value, sizeof(Tcl_ObjCmdProc *)); - - hPtr->clientData = 0; - - return hPtr; -} - -/* - *---------------------------------------------------------------------- * Nsf_CmdDefinitionInit -- * - * Initialize cmd definition structures + * Initialize the hash-table structure for storing the method definitions. * * Results: * None. @@ -210,8 +66,9 @@ NsfMutexLock(&cmdDefinitonMutex); if (cmdDefinitonRefCount == 0) { - // Tcl_InitHashTable(cmdDefinitonHashTablePtr, TCL_ONE_WORD_KEYS); - Tcl_InitCustomHashTable(cmdDefinitonHashTablePtr, TCL_CUSTOM_PTR_KEYS, &cmdPtrHashKeyType); + /* Tcl_InitHashTable(cmdDefinitonHashTablePtr, TCL_ONE_WORD_KEYS); */ + /* Tcl_InitCustomHashTable(cmdDefinitonHashTablePtr, TCL_CUSTOM_PTR_KEYS, &cmdPtrHashKeyType); */ + Nsf_InitFunPtrHashTable(cmdDefinitonHashTablePtr); } cmdDefinitonRefCount++; @@ -251,10 +108,10 @@ *---------------------------------------------------------------------- * Nsf_CmdDefinitionGet -- * - * Obtain the definiton for a registered proc + * Obtain the definiton for a previously registered proc. * * Results: - * method definition or NULL + * A pointer to a Method definition or NULL. * * Side effects: * None. @@ -264,15 +121,13 @@ Nsf_methodDefinition * Nsf_CmdDefinitionGet(Tcl_ObjCmdProc *proc) { Tcl_HashEntry *hPtr; - cmdPtrEntry_t cmdEntry; nonnull_assert(proc != NULL); //fprintf(stderr, "=== Lookup proc %p\n", proc); - cmdEntry.proc = proc; NsfMutexLock(&cmdDefinitonMutex); - hPtr = Tcl_FindHashEntry(cmdDefinitonHashTablePtr, (const char *)&cmdEntry); + hPtr = Nsf_FindFunPtrHashEntry(cmdDefinitonHashTablePtr, (Nsf_AnyFun *)proc); NsfMutexUnlock(&cmdDefinitonMutex); if (hPtr != NULL) { @@ -286,7 +141,7 @@ *---------------------------------------------------------------------- * Register -- * - * Register a method Definition + * Register a method definition. * * Results: * Tcl result code. @@ -302,17 +157,17 @@ Register(Tcl_Interp *interp, Nsf_methodDefinition *methodDefinition) { Tcl_HashEntry *hPtr; int isNew; - cmdPtrEntry_t cmdEntry; + /* cmdPtrEntry_t cmdEntry; */ nonnull_assert(interp != NULL); nonnull_assert(methodDefinition != NULL); //fprintf(stderr, "=== Register proc %p with name %s\n", methodDefinition->proc, methodDefinition->methodName); - cmdEntry.proc = methodDefinition->proc; + /* cmdEntry.proc = methodDefinition->proc; */ NsfMutexLock(&cmdDefinitonMutex); - hPtr = Tcl_CreateHashEntry(cmdDefinitonHashTablePtr, (const char *)&cmdEntry, &isNew); + hPtr = Nsf_CreateFunPtrHashEntry(cmdDefinitonHashTablePtr, (Nsf_AnyFun *)methodDefinition->proc, &isNew); /* Tcl_CreateHashEntry(cmdDefinitonHashTablePtr, (const char *)&cmdEntry, &isNew);*/ NsfMutexUnlock(&cmdDefinitonMutex); - + if (isNew != 0) { Tcl_SetHashValue(hPtr, methodDefinition); return TCL_OK;