summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjan.nijtmans <nijtmans@users.sourceforge.net>2025-04-13 22:16:52 (GMT)
committerjan.nijtmans <nijtmans@users.sourceforge.net>2025-04-13 22:16:52 (GMT)
commit2b0fe4a3ef75940978059b4b33672f2d1c63dced (patch)
tree4d6908ac453dc6ccba9b0a0593e77af3511609c6
parentd46e9784ab0ff5b3e9bf35dc56c903fd9503c936 (diff)
downloadtcl-core-attemptcreatehashentry.zip
tcl-core-attemptcreatehashentry.tar.gz
tcl-core-attemptcreatehashentry.tar.bz2
Implement Tcl_AttemptCreateHashEntry()core-attemptcreatehashentry
-rw-r--r--generic/tcl.h33
-rw-r--r--generic/tclClockFmt.c5
-rw-r--r--generic/tclHash.c23
-rw-r--r--generic/tclObj.c10
-rw-r--r--generic/tclVar.c5
5 files changed, 60 insertions, 16 deletions
diff --git a/generic/tcl.h b/generic/tcl.h
index f2ad6e8..06ca3b7 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -2513,11 +2513,40 @@ TclBounceRefCount(
* hash tables:
*/
-#undef Tcl_FindHashEntry
#define Tcl_FindHashEntry(tablePtr, key) \
(*((tablePtr)->createProc))(tablePtr, (const char *)(key), (int *)-1)
-#undef Tcl_CreateHashEntry
+
+#ifdef TCL_MEM_DEBUG
+static inline Tcl_HashEntry *
+TclDbPanicIfNull(
+ Tcl_HashEntry *entry,
+ int *newPtr,
+ const char *file,
+ const char *line)
+{
+ if (!entry && newPtr != (int *)-1) {
+ Tcl_Panic("%s: Memory overflow in file %s:%d", "Tcl_CreateHashEntry", file, line);
+ }
+ return entry;
+}
+#define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
+ TclDbPanicIfNull((*((tablePtr)->createProc))(tablePtr, (const char *)(key), (newPtr)), (newPtr), __FILE__, __LINE__)
+#else
+static inline Tcl_HashEntry *
+TclPanicIfNull(
+ Tcl_HashEntry *entry,
+ int *newPtr)
+{
+ if (!entry && newPtr != (int *)-1) {
+ Tcl_Panic("%s: Memory overflow", "Tcl_CreateHashEntry");
+ }
+ return entry;
+}
#define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
+ TclPanicIfNull((*((tablePtr)->createProc))(tablePtr, (const char *)(key), (newPtr)), (newPtr))
+#endif
+
+#define Tcl_AttemptCreateHashEntry(tablePtr, key, newPtr) \
(*((tablePtr)->createProc))(tablePtr, (const char *)(key), newPtr)
#endif /* RC_INVOKED */
diff --git a/generic/tclClockFmt.c b/generic/tclClockFmt.c
index 358c4f0..beec218 100644
--- a/generic/tclClockFmt.c
+++ b/generic/tclClockFmt.c
@@ -565,7 +565,10 @@ ClockFmtScnStorageAllocProc(
allocsize -= sizeof(hPtr->key);
}
- fss = (ClockFmtScnStorage *)Tcl_Alloc(allocsize);
+ fss = (ClockFmtScnStorage *)Tcl_AttemptAlloc(allocsize);
+ if (!fss) {
+ return NULL;
+ }
/* initialize */
memset(fss, 0, sizeof(*fss));
diff --git a/generic/tclHash.c b/generic/tclHash.c
index 518ba93..1b4d644 100644
--- a/generic/tclHash.c
+++ b/generic/tclHash.c
@@ -335,7 +335,10 @@ CreateHashEntry(
if (typePtr->allocEntryProc) {
hPtr = typePtr->allocEntryProc(tablePtr, (void *) key);
} else {
- hPtr = (Tcl_HashEntry *)Tcl_Alloc(sizeof(Tcl_HashEntry));
+ hPtr = (Tcl_HashEntry *)Tcl_AttemptAlloc(sizeof(Tcl_HashEntry));
+ if (!hPtr) {
+ return NULL;
+ }
hPtr->key.oneWordValue = (char *) key;
Tcl_SetHashValue(hPtr, NULL);
}
@@ -681,10 +684,12 @@ AllocArrayEntry(
if (size < sizeof(Tcl_HashEntry)) {
size = sizeof(Tcl_HashEntry);
}
- hPtr = (Tcl_HashEntry *)Tcl_Alloc(size);
+ hPtr = (Tcl_HashEntry *)Tcl_AttemptAlloc(size);
- memcpy(hPtr->key.string, keyPtr, count);
- Tcl_SetHashValue(hPtr, NULL);
+ if (hPtr) {
+ memcpy(hPtr->key.string, keyPtr, count);
+ Tcl_SetHashValue(hPtr, NULL);
+ }
return hPtr;
}
@@ -779,10 +784,12 @@ AllocStringEntry(
if (size < sizeof(hPtr->key)) {
allocsize = sizeof(hPtr->key);
}
- hPtr = (Tcl_HashEntry *)Tcl_Alloc(offsetof(Tcl_HashEntry, key) + allocsize);
- memset(hPtr, 0, offsetof(Tcl_HashEntry, key) + allocsize);
- memcpy(hPtr->key.string, string, size);
- Tcl_SetHashValue(hPtr, NULL);
+ hPtr = (Tcl_HashEntry *)Tcl_AttemptAlloc(offsetof(Tcl_HashEntry, key) + allocsize);
+ if (hPtr) {
+ memset(hPtr, 0, offsetof(Tcl_HashEntry, key) + allocsize);
+ memcpy(hPtr->key.string, string, size);
+ Tcl_SetHashValue(hPtr, NULL);
+ }
return hPtr;
}
diff --git a/generic/tclObj.c b/generic/tclObj.c
index e086c87..500338b 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -4184,11 +4184,13 @@ AllocObjEntry(
void *keyPtr) /* Key to store in the hash table entry. */
{
Tcl_Obj *objPtr = (Tcl_Obj *)keyPtr;
- Tcl_HashEntry *hPtr = (Tcl_HashEntry *)Tcl_Alloc(sizeof(Tcl_HashEntry));
+ Tcl_HashEntry *hPtr = (Tcl_HashEntry *)Tcl_AttemptAlloc(sizeof(Tcl_HashEntry));
- hPtr->key.objPtr = objPtr;
- Tcl_IncrRefCount(objPtr);
- hPtr->clientData = NULL;
+ if (hPtr) {
+ hPtr->key.objPtr = objPtr;
+ Tcl_IncrRefCount(objPtr);
+ hPtr->clientData = NULL;
+ }
return hPtr;
}
diff --git a/generic/tclVar.c b/generic/tclVar.c
index 955e4f3..9846102 100644
--- a/generic/tclVar.c
+++ b/generic/tclVar.c
@@ -6730,7 +6730,10 @@ AllocVarEntry(
Tcl_HashEntry *hPtr;
Var *varPtr;
- varPtr = (Var *)Tcl_Alloc(sizeof(VarInHash));
+ varPtr = (Var *)Tcl_AttemptAlloc(sizeof(VarInHash));
+ if (!varPtr) {
+ return NULL;
+ }
varPtr->flags = VAR_IN_HASHTABLE;
varPtr->value.objPtr = NULL;
VarHashRefCount(varPtr) = 1;