Index: generic/tcl.decls ================================================================== --- generic/tcl.decls +++ generic/tcl.decls @@ -38,26 +38,26 @@ } declare 2 { TCL_NORETURN void Tcl_Panic(const char *format, ...) } declare 3 { - void *Tcl_Alloc(TCL_HASH_TYPE size) + void *Tcl_Alloc_(TCL_HASH_TYPE size) } declare 4 { void Tcl_Free(void *ptr) } declare 5 { - void *Tcl_Realloc(void *ptr, TCL_HASH_TYPE size) + void *Tcl_Realloc_(void *ptr, TCL_HASH_TYPE size) } declare 6 { - void *Tcl_DbCkalloc(TCL_HASH_TYPE size, const char *file, int line) + void *Tcl_DbCkalloc_(TCL_HASH_TYPE size, const char *file, int line) } declare 7 { void Tcl_DbCkfree(void *ptr, const char *file, int line) } declare 8 { - void *Tcl_DbCkrealloc(void *ptr, TCL_HASH_TYPE size, + void *Tcl_DbCkrealloc_(void *ptr, TCL_HASH_TYPE size, const char *file, int line) } # Tcl_CreateFileHandler and Tcl_DeleteFileHandler are only available on Unix, # but they are part of the old generic interface, so we include them here for @@ -253,11 +253,11 @@ # Removed in 9.0 (changed to macro): #declare 63 { # void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue) #} declare 64 { - void Tcl_SetObjLength(Tcl_Obj *objPtr, Tcl_Size length) + char *Tcl_SetObjLength_(Tcl_Obj *objPtr, Tcl_Size length) } declare 65 { void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, Tcl_Size length) } # Removed in 9.0, replaced by macro. @@ -1392,11 +1392,11 @@ } declare 378 { Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, Tcl_Size numChars) } declare 379 { - void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, + Tcl_UniChar * Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars) } declare 380 { Tcl_Size TclGetCharLength(Tcl_Obj *objPtr) } @@ -1409,11 +1409,11 @@ #} declare 383 { Tcl_Obj *TclGetRange(Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size last) } declare 384 { - void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, + Tcl_UniChar *Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size length) } declare 385 { int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj) @@ -1576,24 +1576,24 @@ declare 427 { void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData) } declare 428 { - void *Tcl_AttemptAlloc(TCL_HASH_TYPE size) + void *Tcl_Alloc(TCL_HASH_TYPE size) } declare 429 { - void *Tcl_AttemptDbCkalloc(TCL_HASH_TYPE size, const char *file, int line) + void *Tcl_DbCkalloc(TCL_HASH_TYPE size, const char *file, int line) } declare 430 { - void *Tcl_AttemptRealloc(void *ptr, TCL_HASH_TYPE size) + void *Tcl_Realloc(void *ptr, TCL_HASH_TYPE size) } declare 431 { - void *Tcl_AttemptDbCkrealloc(void *ptr, TCL_HASH_TYPE size, + void *Tcl_DbCkrealloc(void *ptr, TCL_HASH_TYPE size, const char *file, int line) } declare 432 { - int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, Tcl_Size length) + char *Tcl_SetObjLength(Tcl_Obj *objPtr, Tcl_Size length) } # TIP#10 (thread-aware channels) akupries declare 433 { Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel) Index: generic/tclCkalloc.c ================================================================== --- generic/tclCkalloc.c +++ generic/tclCkalloc.c @@ -21,12 +21,10 @@ #define TRUE 1 #undef Tcl_Alloc #undef Tcl_Free #undef Tcl_Realloc -#undef Tcl_AttemptAlloc -#undef Tcl_AttemptRealloc #ifdef TCL_MEM_DEBUG /* * One of the following structures is allocated each time the @@ -395,100 +393,10 @@ /* Don't let size argument to TclpAlloc overflow */ if (size <= (size_t)-2 - offsetof(struct mem_header, body) - HIGH_GUARD_SIZE) { result = (struct mem_header *) TclpAlloc(size + offsetof(struct mem_header, body) + 1U + HIGH_GUARD_SIZE); } - if (result == NULL) { - fflush(stdout); - TclDumpMemoryInfo(stderr, 0); - Tcl_Panic("unable to alloc %" TCL_Z_MODIFIER "u bytes, %s line %d", size, file, line); - } - - /* - * Fill in guard zones and size. Also initialize the contents of the block - * with bogus bytes to detect uses of initialized data. Link into - * allocated list. - */ - - if (init_malloced_bodies) { - memset(result, GUARD_VALUE, - offsetof(struct mem_header, body) + 1U + HIGH_GUARD_SIZE + size); - } else { - memset(result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE); - memset(result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE); - } - if (!ckallocInit) { - TclInitDbCkalloc(); - } - Tcl_MutexLock(ckallocMutexPtr); - result->length = size; - result->tagPtr = curTagPtr; - if (curTagPtr != NULL) { - curTagPtr->refCount++; - } - result->file = file; - result->line = line; - result->flink = allocHead; - result->blink = NULL; - - if (allocHead != NULL) { - allocHead->blink = result; - } - allocHead = result; - - total_mallocs++; - if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) { - (void) fflush(stdout); - fprintf(stderr, "reached malloc trace enable point (%" TCL_Z_MODIFIER "u)\n", - total_mallocs); - fflush(stderr); - alloc_tracing = TRUE; - trace_on_at_malloc = 0; - } - - if (alloc_tracing) { - fprintf(stderr,"Tcl_Alloc %p %" TCL_Z_MODIFIER "u %s %d\n", - result->body, size, file, line); - } - - if (break_on_malloc && (total_mallocs >= break_on_malloc)) { - break_on_malloc = 0; - (void) fflush(stdout); - Tcl_Panic("reached malloc break limit (%" TCL_Z_MODIFIER "u)", total_mallocs); - } - - current_malloc_packets++; - if (current_malloc_packets > maximum_malloc_packets) { - maximum_malloc_packets = current_malloc_packets; - } - current_bytes_malloced += size; - if (current_bytes_malloced > maximum_bytes_malloced) { - maximum_bytes_malloced = current_bytes_malloced; - } - - Tcl_MutexUnlock(ckallocMutexPtr); - - return result->body; -} - -void * -Tcl_AttemptDbCkalloc( - size_t size, - const char *file, - int line) -{ - struct mem_header *result = NULL; - - if (validate_memory) { - Tcl_ValidateAllMemory(file, line); - } - - /* Don't let size argument to TclpAlloc overflow */ - if (size <= (size_t)-2 - offsetof(struct mem_header, body) - HIGH_GUARD_SIZE) { - result = (struct mem_header *) TclpAlloc(size + - offsetof(struct mem_header, body) + 1U + HIGH_GUARD_SIZE); - } if (result == NULL) { fflush(stdout); TclDumpMemoryInfo(stderr, 0); return NULL; } @@ -678,41 +586,10 @@ copySize = size; if (copySize > memp->length) { copySize = memp->length; } newPtr = (char *)Tcl_DbCkalloc(size, file, line); - memcpy(newPtr, ptr, copySize); - Tcl_DbCkfree(ptr, file, line); - return newPtr; -} - -void * -Tcl_AttemptDbCkrealloc( - void *ptr, - size_t size, - const char *file, - int line) -{ - char *newPtr; - size_t copySize; - struct mem_header *memp; - - if (ptr == NULL) { - return Tcl_AttemptDbCkalloc(size, file, line); - } - - /* - * See comment from Tcl_DbCkfree before you change the following line. - */ - - memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET); - - copySize = size; - if (copySize > memp->length) { - copySize = memp->length; - } - newPtr = (char *)Tcl_AttemptDbCkalloc(size, file, line); if (newPtr == NULL) { return NULL; } memcpy(newPtr, ptr, copySize); Tcl_DbCkfree(ptr, file, line); @@ -742,17 +619,10 @@ size_t size) { return Tcl_DbCkalloc(size, "unknown", 0); } -void * -Tcl_AttemptAlloc( - size_t size) -{ - return Tcl_AttemptDbCkalloc(size, "unknown", 0); -} - void Tcl_Free( void *ptr) { Tcl_DbCkfree(ptr, "unknown", 0); @@ -763,17 +633,10 @@ void *ptr, size_t size) { return Tcl_DbCkrealloc(ptr, size, "unknown", 0); } -void * -Tcl_AttemptRealloc( - void *ptr, - size_t size) -{ - return Tcl_AttemptDbCkrealloc(ptr, size, "unknown", 0); -} /* *---------------------------------------------------------------------- * * MemoryCmd -- @@ -1022,75 +885,26 @@ /* *---------------------------------------------------------------------- * * Tcl_Alloc -- * - * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does check - * that memory was actually allocated. + * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not + * check that memory was actually allocated. * *---------------------------------------------------------------------- */ void * Tcl_Alloc( size_t size) { - void *result = TclpAlloc(size); - - /* - * Most systems will not alloc(0), instead bumping it to one so that NULL - * isn't returned. Some systems (AIX, Tru64) will alloc(0) by returning - * NULL, so we have to check that the NULL we get is not in response to - * alloc(0). - * - * The ANSI spec actually says that systems either return NULL *or* a - * special pointer on failure, but we only check for NULL - */ - - if ((result == NULL) && size) { - Tcl_Panic("unable to alloc %" TCL_Z_MODIFIER "u bytes", size); - } - return result; + return (char *)TclpAlloc(size); } void * Tcl_DbCkalloc( size_t size, - const char *file, - int line) -{ - void *result = TclpAlloc(size); - - if ((result == NULL) && size) { - fflush(stdout); - Tcl_Panic("unable to alloc %" TCL_Z_MODIFIER "u bytes, %s line %d", - size, file, line); - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AttemptAlloc -- - * - * Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not - * check that memory was actually allocated. - * - *---------------------------------------------------------------------- - */ - -void * -Tcl_AttemptAlloc( - size_t size) -{ - return (char *)TclpAlloc(size); -} - -void * -Tcl_AttemptDbCkalloc( - size_t size, TCL_UNUSED(const char *) /*file*/, TCL_UNUSED(int) /*line*/) { return (char *)TclpAlloc(size); } @@ -1098,68 +912,27 @@ /* *---------------------------------------------------------------------- * * Tcl_Realloc -- * - * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does check - * that memory was actually allocated. + * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does not + * check that memory was actually allocated. * *---------------------------------------------------------------------- */ void * Tcl_Realloc( void *ptr, size_t size) { - void *result = TclpRealloc(ptr, size); - - if ((result == NULL) && size) { - Tcl_Panic("unable to realloc %" TCL_Z_MODIFIER "u bytes", size); - } - return result; + return (char *)TclpRealloc(ptr, size); } void * Tcl_DbCkrealloc( void *ptr, - size_t size, - const char *file, - int line) -{ - void *result = TclpRealloc(ptr, size); - - if ((result == NULL) && size) { - fflush(stdout); - Tcl_Panic("unable to realloc %" TCL_Z_MODIFIER "u bytes, %s line %d", - size, file, line); - } - return result; -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AttemptRealloc -- - * - * Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does not - * check that memory was actually allocated. - * - *---------------------------------------------------------------------- - */ - -void * -Tcl_AttemptRealloc( - void *ptr, - size_t size) -{ - return (char *)TclpRealloc(ptr, size); -} - -void * -Tcl_AttemptDbCkrealloc( - void *ptr, size_t size, TCL_UNUSED(const char *) /*file*/, TCL_UNUSED(int) /*line*/) { return (char *)TclpRealloc(ptr, size); Index: generic/tclDecls.h ================================================================== --- generic/tclDecls.h +++ generic/tclDecls.h @@ -59,22 +59,22 @@ const char *name, const char *version, int exact, void *clientDataPtr); /* 2 */ EXTERN TCL_NORETURN void Tcl_Panic(const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 3 */ -EXTERN void * Tcl_Alloc(TCL_HASH_TYPE size); +EXTERN void * Tcl_Alloc_(TCL_HASH_TYPE size); /* 4 */ EXTERN void Tcl_Free(void *ptr); /* 5 */ -EXTERN void * Tcl_Realloc(void *ptr, TCL_HASH_TYPE size); +EXTERN void * Tcl_Realloc_(void *ptr, TCL_HASH_TYPE size); /* 6 */ -EXTERN void * Tcl_DbCkalloc(TCL_HASH_TYPE size, const char *file, +EXTERN void * Tcl_DbCkalloc_(TCL_HASH_TYPE size, const char *file, int line); /* 7 */ EXTERN void Tcl_DbCkfree(void *ptr, const char *file, int line); /* 8 */ -EXTERN void * Tcl_DbCkrealloc(void *ptr, TCL_HASH_TYPE size, +EXTERN void * Tcl_DbCkrealloc_(void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 9 */ EXTERN void Tcl_CreateFileHandler(int fd, int mask, Tcl_FileProc *proc, void *clientData); /* 10 */ @@ -209,11 +209,11 @@ /* 62 */ EXTERN void Tcl_SetListObj(Tcl_Obj *objPtr, Tcl_Size objc, Tcl_Obj *const objv[]); /* Slot 63 is reserved */ /* 64 */ -EXTERN void Tcl_SetObjLength(Tcl_Obj *objPtr, Tcl_Size length); +EXTERN char * Tcl_SetObjLength_(Tcl_Obj *objPtr, Tcl_Size length); /* 65 */ EXTERN void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, Tcl_Size length); /* Slot 66 is reserved */ /* Slot 67 is reserved */ @@ -997,11 +997,11 @@ Tcl_RegExpInfo *infoPtr); /* 378 */ EXTERN Tcl_Obj * Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, Tcl_Size numChars); /* 379 */ -EXTERN void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, +EXTERN Tcl_UniChar * Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars); /* 380 */ EXTERN Tcl_Size TclGetCharLength(Tcl_Obj *objPtr); /* 381 */ @@ -1009,11 +1009,11 @@ /* Slot 382 is reserved */ /* 383 */ EXTERN Tcl_Obj * TclGetRange(Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size last); /* 384 */ -EXTERN void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, +EXTERN Tcl_UniChar * Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size length); /* 385 */ EXTERN int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 386 */ @@ -1120,22 +1120,21 @@ /* 427 */ EXTERN void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData); /* 428 */ -EXTERN void * Tcl_AttemptAlloc(TCL_HASH_TYPE size); +EXTERN void * Tcl_Alloc(TCL_HASH_TYPE size); /* 429 */ -EXTERN void * Tcl_AttemptDbCkalloc(TCL_HASH_TYPE size, - const char *file, int line); +EXTERN void * Tcl_DbCkalloc(TCL_HASH_TYPE size, const char *file, + int line); /* 430 */ -EXTERN void * Tcl_AttemptRealloc(void *ptr, TCL_HASH_TYPE size); +EXTERN void * Tcl_Realloc(void *ptr, TCL_HASH_TYPE size); /* 431 */ -EXTERN void * Tcl_AttemptDbCkrealloc(void *ptr, TCL_HASH_TYPE size, +EXTERN void * Tcl_DbCkrealloc(void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 432 */ -EXTERN int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, - Tcl_Size length); +EXTERN char * Tcl_SetObjLength(Tcl_Obj *objPtr, Tcl_Size length); /* 433 */ EXTERN Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel); /* 434 */ EXTERN Tcl_UniChar * TclGetUnicodeFromObj(Tcl_Obj *objPtr, void *lengthPtr); @@ -1880,16 +1879,16 @@ const TclStubHooks *hooks; int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */ const char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */ TCL_NORETURN1 void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */ - void * (*tcl_Alloc) (TCL_HASH_TYPE size); /* 3 */ + void * (*tcl_Alloc_) (TCL_HASH_TYPE size); /* 3 */ void (*tcl_Free) (void *ptr); /* 4 */ - void * (*tcl_Realloc) (void *ptr, TCL_HASH_TYPE size); /* 5 */ - void * (*tcl_DbCkalloc) (TCL_HASH_TYPE size, const char *file, int line); /* 6 */ + void * (*tcl_Realloc_) (void *ptr, TCL_HASH_TYPE size); /* 5 */ + void * (*tcl_DbCkalloc_) (TCL_HASH_TYPE size, const char *file, int line); /* 6 */ void (*tcl_DbCkfree) (void *ptr, const char *file, int line); /* 7 */ - void * (*tcl_DbCkrealloc) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 8 */ + void * (*tcl_DbCkrealloc_) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 8 */ void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, void *clientData); /* 9 */ void (*tcl_DeleteFileHandler) (int fd); /* 10 */ void (*tcl_SetTimer) (const Tcl_Time *timePtr); /* 11 */ void (*tcl_Sleep) (int ms); /* 12 */ int (*tcl_WaitForEvent) (const Tcl_Time *timePtr); /* 13 */ @@ -1941,11 +1940,11 @@ void (*tcl_SetByteArrayObj) (Tcl_Obj *objPtr, const unsigned char *bytes, Tcl_Size numBytes); /* 59 */ void (*tcl_SetDoubleObj) (Tcl_Obj *objPtr, double doubleValue); /* 60 */ void (*reserved61)(void); void (*tcl_SetListObj) (Tcl_Obj *objPtr, Tcl_Size objc, Tcl_Obj *const objv[]); /* 62 */ void (*reserved63)(void); - void (*tcl_SetObjLength) (Tcl_Obj *objPtr, Tcl_Size length); /* 64 */ + char * (*tcl_SetObjLength_) (Tcl_Obj *objPtr, Tcl_Size length); /* 64 */ void (*tcl_SetStringObj) (Tcl_Obj *objPtr, const char *bytes, Tcl_Size length); /* 65 */ void (*reserved66)(void); void (*reserved67)(void); void (*tcl_AllowExceptions) (Tcl_Interp *interp); /* 68 */ void (*tcl_AppendElement) (Tcl_Interp *interp, const char *element); /* 69 */ @@ -2256,16 +2255,16 @@ int (*tcl_UniCharIsPrint) (int ch); /* 374 */ int (*tcl_UniCharIsPunct) (int ch); /* 375 */ int (*tcl_RegExpExecObj) (Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, Tcl_Size offset, Tcl_Size nmatches, int flags); /* 376 */ void (*tcl_RegExpGetInfo) (Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 377 */ Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, Tcl_Size numChars); /* 378 */ - void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars); /* 379 */ + Tcl_UniChar * (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars); /* 379 */ Tcl_Size (*tclGetCharLength) (Tcl_Obj *objPtr); /* 380 */ int (*tclGetUniChar) (Tcl_Obj *objPtr, Tcl_Size index); /* 381 */ void (*reserved382)(void); Tcl_Obj * (*tclGetRange) (Tcl_Obj *objPtr, Tcl_Size first, Tcl_Size last); /* 383 */ - void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size length); /* 384 */ + Tcl_UniChar * (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size length); /* 384 */ int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */ void (*tcl_SetNotifier) (const Tcl_NotifierProcs *notifierProcPtr); /* 386 */ Tcl_Mutex * (*tcl_GetAllocMutex) (void); /* 387 */ int (*tcl_GetChannelNames) (Tcl_Interp *interp); /* 388 */ int (*tcl_GetChannelNamesEx) (Tcl_Interp *interp, const char *pattern); /* 389 */ @@ -2305,15 +2304,15 @@ void (*tcl_InitCustomHashTable) (Tcl_HashTable *tablePtr, int keyType, const Tcl_HashKeyType *typePtr); /* 423 */ void (*tcl_InitObjHashTable) (Tcl_HashTable *tablePtr); /* 424 */ void * (*tcl_CommandTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *procPtr, void *prevClientData); /* 425 */ int (*tcl_TraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData); /* 426 */ void (*tcl_UntraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, void *clientData); /* 427 */ - void * (*tcl_AttemptAlloc) (TCL_HASH_TYPE size); /* 428 */ - void * (*tcl_AttemptDbCkalloc) (TCL_HASH_TYPE size, const char *file, int line); /* 429 */ - void * (*tcl_AttemptRealloc) (void *ptr, TCL_HASH_TYPE size); /* 430 */ - void * (*tcl_AttemptDbCkrealloc) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 431 */ - int (*tcl_AttemptSetObjLength) (Tcl_Obj *objPtr, Tcl_Size length); /* 432 */ + void * (*tcl_Alloc) (TCL_HASH_TYPE size); /* 428 */ + void * (*tcl_DbCkalloc) (TCL_HASH_TYPE size, const char *file, int line); /* 429 */ + void * (*tcl_Realloc) (void *ptr, TCL_HASH_TYPE size); /* 430 */ + void * (*tcl_DbCkrealloc) (void *ptr, TCL_HASH_TYPE size, const char *file, int line); /* 431 */ + char * (*tcl_SetObjLength) (Tcl_Obj *objPtr, Tcl_Size length); /* 432 */ Tcl_ThreadId (*tcl_GetChannelThread) (Tcl_Channel channel); /* 433 */ Tcl_UniChar * (*tclGetUnicodeFromObj) (Tcl_Obj *objPtr, void *lengthPtr); /* 434 */ void (*reserved435)(void); void (*reserved436)(void); Tcl_Obj * (*tcl_SubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 437 */ @@ -2586,22 +2585,22 @@ (tclStubsPtr->tcl_PkgProvideEx) /* 0 */ #define Tcl_PkgRequireEx \ (tclStubsPtr->tcl_PkgRequireEx) /* 1 */ #define Tcl_Panic \ (tclStubsPtr->tcl_Panic) /* 2 */ -#define Tcl_Alloc \ - (tclStubsPtr->tcl_Alloc) /* 3 */ +#define Tcl_Alloc_ \ + (tclStubsPtr->tcl_Alloc_) /* 3 */ #define Tcl_Free \ (tclStubsPtr->tcl_Free) /* 4 */ -#define Tcl_Realloc \ - (tclStubsPtr->tcl_Realloc) /* 5 */ -#define Tcl_DbCkalloc \ - (tclStubsPtr->tcl_DbCkalloc) /* 6 */ +#define Tcl_Realloc_ \ + (tclStubsPtr->tcl_Realloc_) /* 5 */ +#define Tcl_DbCkalloc_ \ + (tclStubsPtr->tcl_DbCkalloc_) /* 6 */ #define Tcl_DbCkfree \ (tclStubsPtr->tcl_DbCkfree) /* 7 */ -#define Tcl_DbCkrealloc \ - (tclStubsPtr->tcl_DbCkrealloc) /* 8 */ +#define Tcl_DbCkrealloc_ \ + (tclStubsPtr->tcl_DbCkrealloc_) /* 8 */ #define Tcl_CreateFileHandler \ (tclStubsPtr->tcl_CreateFileHandler) /* 9 */ #define Tcl_DeleteFileHandler \ (tclStubsPtr->tcl_DeleteFileHandler) /* 10 */ #define Tcl_SetTimer \ @@ -2699,12 +2698,12 @@ (tclStubsPtr->tcl_SetDoubleObj) /* 60 */ /* Slot 61 is reserved */ #define Tcl_SetListObj \ (tclStubsPtr->tcl_SetListObj) /* 62 */ /* Slot 63 is reserved */ -#define Tcl_SetObjLength \ - (tclStubsPtr->tcl_SetObjLength) /* 64 */ +#define Tcl_SetObjLength_ \ + (tclStubsPtr->tcl_SetObjLength_) /* 64 */ #define Tcl_SetStringObj \ (tclStubsPtr->tcl_SetStringObj) /* 65 */ /* Slot 66 is reserved */ /* Slot 67 is reserved */ #define Tcl_AllowExceptions \ @@ -3377,20 +3376,20 @@ (tclStubsPtr->tcl_CommandTraceInfo) /* 425 */ #define Tcl_TraceCommand \ (tclStubsPtr->tcl_TraceCommand) /* 426 */ #define Tcl_UntraceCommand \ (tclStubsPtr->tcl_UntraceCommand) /* 427 */ -#define Tcl_AttemptAlloc \ - (tclStubsPtr->tcl_AttemptAlloc) /* 428 */ -#define Tcl_AttemptDbCkalloc \ - (tclStubsPtr->tcl_AttemptDbCkalloc) /* 429 */ -#define Tcl_AttemptRealloc \ - (tclStubsPtr->tcl_AttemptRealloc) /* 430 */ -#define Tcl_AttemptDbCkrealloc \ - (tclStubsPtr->tcl_AttemptDbCkrealloc) /* 431 */ -#define Tcl_AttemptSetObjLength \ - (tclStubsPtr->tcl_AttemptSetObjLength) /* 432 */ +#define Tcl_Alloc \ + (tclStubsPtr->tcl_Alloc) /* 428 */ +#define Tcl_DbCkalloc \ + (tclStubsPtr->tcl_DbCkalloc) /* 429 */ +#define Tcl_Realloc \ + (tclStubsPtr->tcl_Realloc) /* 430 */ +#define Tcl_DbCkrealloc \ + (tclStubsPtr->tcl_DbCkrealloc) /* 431 */ +#define Tcl_SetObjLength \ + (tclStubsPtr->tcl_SetObjLength) /* 432 */ #define Tcl_GetChannelThread \ (tclStubsPtr->tcl_GetChannelThread) /* 433 */ #define TclGetUnicodeFromObj \ (tclStubsPtr->tclGetUnicodeFromObj) /* 434 */ /* Slot 435 is reserved */ @@ -4098,10 +4097,14 @@ (sizeof(*(sizePtr)) <= sizeof(int) ? \ TclGetUnicodeFromObj(objPtr, (sizePtr)) : \ (Tcl_GetUnicodeFromObj)(objPtr, (Tcl_Size *)(void *)(sizePtr))) #endif +#define Tcl_AttemptAlloc Tcl_Alloc +#define Tcl_AttemptRealloc Tcl_Realloc +#define Tcl_AttemptSetObjLength Tcl_SetObjLength + #ifdef TCL_MEM_DEBUG # undef Tcl_Alloc # define Tcl_Alloc(x) \ (Tcl_DbCkalloc((x), __FILE__, __LINE__)) # undef Tcl_Free @@ -4108,16 +4111,10 @@ # define Tcl_Free(x) \ Tcl_DbCkfree((x), __FILE__, __LINE__) # undef Tcl_Realloc # define Tcl_Realloc(x,y) \ (Tcl_DbCkrealloc((x), (y), __FILE__, __LINE__)) -# undef Tcl_AttemptAlloc -# define Tcl_AttemptAlloc(x) \ - (Tcl_AttemptDbCkalloc((x), __FILE__, __LINE__)) -# undef Tcl_AttemptRealloc -# define Tcl_AttemptRealloc(x,y) \ - (Tcl_AttemptDbCkrealloc((x), (y), __FILE__, __LINE__)) #endif /* !TCL_MEM_DEBUG */ #define Tcl_NewLongObj(value) Tcl_NewWideIntObj((long)(value)) #define Tcl_NewIntObj(value) Tcl_NewWideIntObj((int)(value)) #define Tcl_DbNewLongObj(value, file, line) Tcl_DbNewWideIntObj((long)(value), file, line) Index: generic/tclInt.h ================================================================== --- generic/tclInt.h +++ generic/tclInt.h @@ -5178,12 +5178,12 @@ #include "tclIntDecls.h" #include "tclIntPlatDecls.h" #if !defined(USE_TCL_STUBS) && !defined(TCL_MEM_DEBUG) -#define Tcl_AttemptAlloc TclpAlloc -#define Tcl_AttemptRealloc TclpRealloc +#define Tcl_Alloc TclpAlloc +#define Tcl_Realloc TclpRealloc #define Tcl_Free TclpFree #endif /* * Special hack for macOS, where the static linker (technically the 'ar' Index: generic/tclStringObj.c ================================================================== --- generic/tclStringObj.c +++ generic/tclStringObj.c @@ -60,11 +60,11 @@ static void FillUnicodeRep(Tcl_Obj *objPtr); static void FreeStringInternalRep(Tcl_Obj *objPtr); static void GrowStringBuffer(Tcl_Obj *objPtr, size_t needed, int flag); static void GrowUnicodeBuffer(Tcl_Obj *objPtr, size_t needed); static int SetStringFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); -static void SetUnicodeObj(Tcl_Obj *objPtr, +static Tcl_UniChar *SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode, Tcl_Size numChars); static Tcl_Size UnicodeLength(const Tcl_UniChar *unicode); static void UpdateStringOfString(Tcl_Obj *objPtr); #if TCL_UTF_MAX > 3 @@ -374,11 +374,14 @@ * string. */ { Tcl_Obj *objPtr; TclNewObj(objPtr); - SetUnicodeObj(objPtr, unicode, numChars); + if (!SetUnicodeObj(objPtr, unicode, numChars)) { + Tcl_DecrRefCount(objPtr); + return NULL; + } return objPtr; } /* *---------------------------------------------------------------------- @@ -948,109 +951,15 @@ /* *---------------------------------------------------------------------- * * Tcl_SetObjLength -- * - * Changes the length of the string representation of objPtr. - * - * Results: - * None. - * - * Side effects: - * If the size of objPtr's string representation is greater than length, a - * new terminating null byte is stored in objPtr->bytes at length, and - * bytes at positions past length have no meaning. If the length of the - * string representation is greater than length, the storage space is - * reallocated to length+1. - * - * The object's internal representation is changed to &tclStringType. - * - *---------------------------------------------------------------------- - */ - -void -Tcl_SetObjLength( - Tcl_Obj *objPtr, /* Pointer to object. This object must not - * currently be shared. */ - Tcl_Size length) /* Number of bytes desired for string - * representation of object, not including - * terminating null byte. */ -{ - String *stringPtr; - - if (length < 0) { - Tcl_Panic("Tcl_SetObjLength: length requested is negative: " - "%" TCL_SIZE_MODIFIER "d (integer overflow?)", length); - } - if (Tcl_IsShared(objPtr)) { - Tcl_Panic("%s called with shared object", "Tcl_SetObjLength"); - } - - if (objPtr->bytes && objPtr->length == length) { - return; - } - - SetStringFromAny(NULL, objPtr); - stringPtr = GET_STRING(objPtr); - - if (objPtr->bytes != NULL) { - /* - * Change length of an existing string rep. - */ - if (length > stringPtr->allocated) { - /* - * Need to enlarge the buffer. - */ - if (objPtr->bytes == &tclEmptyString) { - objPtr->bytes = (char *)Tcl_Alloc(length + 1); - } else { - objPtr->bytes = (char *)Tcl_Realloc(objPtr->bytes, length + 1); - } - stringPtr->allocated = length; - } - - objPtr->length = length; - objPtr->bytes[length] = 0; - - /* - * Invalidate the Unicode data. - */ - - stringPtr->numChars = TCL_INDEX_NONE; - stringPtr->hasUnicode = 0; - } else { - if (length > stringPtr->maxChars) { - stringPtr = stringRealloc(stringPtr, length); - SET_STRING(objPtr, stringPtr); - stringPtr->maxChars = length; - } - - /* - * Mark the new end of the Unicode string - */ - - stringPtr->numChars = length; - stringPtr->unicode[length] = 0; - stringPtr->hasUnicode = 1; - - /* - * Can only get here when objPtr->bytes == NULL. No need to invalidate - * the string rep. - */ - } -} - -/* - *---------------------------------------------------------------------- - * - * Tcl_AttemptSetObjLength -- - * * This function changes the length of the string representation of an - * object. It uses the attempt* (non-panic'ing) memory allocators. + * object. * * Results: - * 1 if the requested memory was allocated, 0 otherwise. + * != NULL if the requested memory was allocated, NULL otherwise. * * Side effects: * If the size of objPtr's string representation is greater than length, * then it is reduced to length and a new terminating null byte is stored * in the strength. If the length of the string representation is greater @@ -1060,12 +969,12 @@ * representation is changed to "expendable string". * *---------------------------------------------------------------------- */ -int -Tcl_AttemptSetObjLength( +char * +Tcl_SetObjLength( Tcl_Obj *objPtr, /* Pointer to object. This object must not * currently be shared. */ Tcl_Size length) /* Number of bytes desired for string * representation of object, not including * terminating null byte. */ @@ -1072,18 +981,18 @@ { String *stringPtr; if (length < 0) { /* Negative lengths => most likely integer overflow */ - return 0; + return NULL; } if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_AttemptSetObjLength"); } if (objPtr->bytes && objPtr->length == length) { - return 1; + return objPtr->bytes; } SetStringFromAny(NULL, objPtr); stringPtr = GET_STRING(objPtr); @@ -1102,11 +1011,11 @@ newBytes = (char *)Tcl_AttemptAlloc(length + 1); } else { newBytes = (char *)Tcl_AttemptRealloc(objPtr->bytes, length + 1); } if (newBytes == NULL) { - return 0; + return NULL; } objPtr->bytes = newBytes; stringPtr->allocated = length; } @@ -1144,11 +1053,11 @@ /* * Can only get here when objPtr->bytes == NULL. No need to invalidate * the string rep. */ } - return 1; + return (char *)INT2PTR(-1); } /* *--------------------------------------------------------------------------- * @@ -1163,11 +1072,11 @@ * Memory allocated for new "String" internal rep. * *--------------------------------------------------------------------------- */ -void +Tcl_UniChar * Tcl_SetUnicodeObj( Tcl_Obj *objPtr, /* The object to set the string of. */ const Tcl_UniChar *unicode, /* The Unicode string used to initialize the * object. */ Tcl_Size numChars) /* Number of characters in the Unicode @@ -1175,11 +1084,11 @@ { if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_SetUnicodeObj"); } TclFreeInternalRep(objPtr); - SetUnicodeObj(objPtr, unicode, numChars); + return SetUnicodeObj(objPtr, unicode, numChars); } static Tcl_Size UnicodeLength( const Tcl_UniChar *unicode) @@ -1193,11 +1102,11 @@ } } return numChars; } -static void +static Tcl_UniChar * SetUnicodeObj( Tcl_Obj *objPtr, /* The object to set the string of. */ const Tcl_UniChar *unicode, /* The Unicode string used to initialize the * object. */ Tcl_Size numChars) /* Number of characters in the Unicode @@ -1212,10 +1121,13 @@ /* * Allocate enough space for the String structure + Unicode string. */ stringPtr = stringAlloc(numChars); + if (!stringPtr) { + return NULL; + } SET_STRING(objPtr, stringPtr); objPtr->typePtr = &tclStringType; stringPtr->maxChars = numChars; memcpy(stringPtr->unicode, unicode, numChars * sizeof(Tcl_UniChar)); @@ -1223,10 +1135,11 @@ stringPtr->numChars = numChars; stringPtr->hasUnicode = 1; TclInvalidateStringRep(objPtr); stringPtr->allocated = 0; + return stringPtr->unicode; } /* *---------------------------------------------------------------------- * @@ -1368,11 +1281,11 @@ * Invalidates the string rep and creates a new Unicode string. * *---------------------------------------------------------------------- */ -void +Tcl_UniChar * Tcl_AppendUnicodeToObj( Tcl_Obj *objPtr, /* Points to the object to append to. */ const Tcl_UniChar *unicode, /* The Unicode string to append to the * object. */ Tcl_Size length) /* Number of chars in Unicode. Negative @@ -1383,11 +1296,11 @@ if (Tcl_IsShared(objPtr)) { Tcl_Panic("%s called with shared object", "Tcl_AppendUnicodeToObj"); } if (length == 0) { - return; + return NULL; } SetStringFromAny(NULL, objPtr); stringPtr = GET_STRING(objPtr); @@ -1397,12 +1310,14 @@ * objPtr's string rep. */ if (stringPtr->hasUnicode) { AppendUnicodeToUnicodeRep(objPtr, unicode, length); + return stringPtr->unicode; } else { AppendUnicodeToUtfRep(objPtr, unicode, length); + return (Tcl_UniChar *)INT2PTR(-1); } } /* *---------------------------------------------------------------------- @@ -4368,11 +4283,12 @@ * SetStringFromAny -- * * Create an internal representation of type "String" for an object. * * Results: - * This operation always succeeds and returns TCL_OK. + * This operation always succeeds and returns TCL_OK, except when + * not enough memory can be allocated. * * Side effects: * Any old internal representation for objPtr is freed and the internal * representation is set to &tclStringType. * @@ -4379,28 +4295,35 @@ *---------------------------------------------------------------------- */ static int SetStringFromAny( - TCL_UNUSED(Tcl_Interp *), + Tcl_Interp *interp, Tcl_Obj *objPtr) /* The object to convert. */ { if (!TclHasInternalRep(objPtr, &tclStringType)) { - String *stringPtr = stringAlloc(0); /* * Convert whatever we have into an untyped value. Just A String. */ - (void) TclGetString(objPtr); + if (TclGetString(objPtr) == NULL) { + if (interp != NULL) { + Tcl_AppendResult( interp, + "Cannot allocate string", -1); + Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL); + } + return TCL_ERROR; + } TclFreeInternalRep(objPtr); /* * Create a basic String internalrep that just points to the UTF-8 string * already in place at objPtr->bytes. */ + String *stringPtr = stringAlloc(0); stringPtr->numChars = -1; stringPtr->allocated = objPtr->length; stringPtr->maxChars = 0; stringPtr->hasUnicode = 0; SET_STRING(objPtr, stringPtr); Index: generic/tclStubInit.c ================================================================== --- generic/tclStubInit.c +++ generic/tclStubInit.c @@ -103,17 +103,30 @@ Tcl_Panic("This extension uses a deprecated function, not available now: Tcl is compiled with -DTCL_UTF_MAX==%d", TCL_UTF_MAX); } # define Tcl_GetUnicodeFromObj (Tcl_UniChar *(*)(Tcl_Obj *, Tcl_Size *))(void *)uniCodePanic # define TclGetUnicodeFromObj (Tcl_UniChar *(*)(Tcl_Obj *, int *))(void *)uniCodePanic # define Tcl_NewUnicodeObj (Tcl_Obj *(*)(const Tcl_UniChar *, Tcl_Size))(void *)uniCodePanic -# define Tcl_SetUnicodeObj (void(*)(Tcl_Obj *, const Tcl_UniChar *, Tcl_Size))(void *)uniCodePanic +# define Tcl_SetUnicodeObj (Tcl_UniChar *(*)(Tcl_Obj *, const Tcl_UniChar *, Tcl_Size))(void *)uniCodePanic # define Tcl_AppendUnicodeToObj (void(*)(Tcl_Obj *, const Tcl_UniChar *, Tcl_Size))(void *)uniCodePanic #endif #define TclUtfCharComplete Tcl_UtfCharComplete #define TclUtfNext Tcl_UtfNext #define TclUtfPrev Tcl_UtfPrev + +/* Those entries can be removed before Tcl 9.0 final. + * It's not done now, because _ALL_ extensions then + * need to be re-compiled, they will break otherwise. + * Suggestions: remove those just after the 9.0b1 + * official release, many people will re-compile + * their extensions then anyway. + */ +#define Tcl_Alloc_ Tcl_Alloc +#define Tcl_Realloc_ Tcl_Realloc +#define Tcl_DbCkalloc_ Tcl_DbCkalloc +#define Tcl_DbCkrealloc_ Tcl_DbCkrealloc +#define Tcl_SetObjLength_ Tcl_SetObjLength #if defined(TCL_NO_DEPRECATED) # define TclListObjGetElements 0 # define TclListObjLength 0 # define TclDictObjSize 0 @@ -827,16 +840,16 @@ TCL_STUB_MAGIC, &tclStubHooks, Tcl_PkgProvideEx, /* 0 */ Tcl_PkgRequireEx, /* 1 */ Tcl_Panic, /* 2 */ - Tcl_Alloc, /* 3 */ + Tcl_Alloc_, /* 3 */ Tcl_Free, /* 4 */ - Tcl_Realloc, /* 5 */ - Tcl_DbCkalloc, /* 6 */ + Tcl_Realloc_, /* 5 */ + Tcl_DbCkalloc_, /* 6 */ Tcl_DbCkfree, /* 7 */ - Tcl_DbCkrealloc, /* 8 */ + Tcl_DbCkrealloc_, /* 8 */ Tcl_CreateFileHandler, /* 9 */ Tcl_DeleteFileHandler, /* 10 */ Tcl_SetTimer, /* 11 */ Tcl_Sleep, /* 12 */ Tcl_WaitForEvent, /* 13 */ @@ -888,11 +901,11 @@ Tcl_SetByteArrayObj, /* 59 */ Tcl_SetDoubleObj, /* 60 */ 0, /* 61 */ Tcl_SetListObj, /* 62 */ 0, /* 63 */ - Tcl_SetObjLength, /* 64 */ + Tcl_SetObjLength_, /* 64 */ Tcl_SetStringObj, /* 65 */ 0, /* 66 */ 0, /* 67 */ Tcl_AllowExceptions, /* 68 */ Tcl_AppendElement, /* 69 */ @@ -1252,15 +1265,15 @@ Tcl_InitCustomHashTable, /* 423 */ Tcl_InitObjHashTable, /* 424 */ Tcl_CommandTraceInfo, /* 425 */ Tcl_TraceCommand, /* 426 */ Tcl_UntraceCommand, /* 427 */ - Tcl_AttemptAlloc, /* 428 */ - Tcl_AttemptDbCkalloc, /* 429 */ - Tcl_AttemptRealloc, /* 430 */ - Tcl_AttemptDbCkrealloc, /* 431 */ - Tcl_AttemptSetObjLength, /* 432 */ + Tcl_Alloc, /* 428 */ + Tcl_DbCkalloc, /* 429 */ + Tcl_Realloc, /* 430 */ + Tcl_DbCkrealloc, /* 431 */ + Tcl_SetObjLength, /* 432 */ Tcl_GetChannelThread, /* 433 */ TclGetUnicodeFromObj, /* 434 */ 0, /* 435 */ 0, /* 436 */ Tcl_SubstObj, /* 437 */