diff options
| -rw-r--r-- | generic/tclCompile.c | 8 | ||||
| -rw-r--r-- | generic/tclDisassemble.c | 13 | ||||
| -rw-r--r-- | generic/tclExecute.c | 4 | ||||
| -rw-r--r-- | generic/tclHash.c | 28 | ||||
| -rw-r--r-- | generic/tclInt.h | 26 | ||||
| -rw-r--r-- | generic/tclProc.c | 2 | ||||
| -rw-r--r-- | generic/tclTest.c | 47 |
7 files changed, 81 insertions, 47 deletions
diff --git a/generic/tclCompile.c b/generic/tclCompile.c index 80d8a09..2d22dc1 100644 --- a/generic/tclCompile.c +++ b/generic/tclCompile.c @@ -2838,9 +2838,13 @@ TclInitByteCode( /* * Compute the total number of bytes needed for this bytecode. + * + * Note that code bytes need not be aligned but since later elements are we + * need to pad anyway, either directly after ByteCode or after codeBytes, + * and it's easier and more consistent to do the former. */ - structureSize = sizeof(ByteCode); + structureSize = TCL_ALIGN(sizeof(ByteCode)); /* align code bytes */ structureSize += TCL_ALIGN(codeBytes); /* align object array */ structureSize += TCL_ALIGN(objArrayBytes); /* align exc range arr */ structureSize += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */ @@ -2879,7 +2883,7 @@ TclInitByteCode( codePtr->maxExceptDepth = envPtr->maxExceptDepth; codePtr->maxStackDepth = envPtr->maxStackDepth; - p += sizeof(ByteCode); + p += TCL_ALIGN(sizeof(ByteCode)); /* align code bytes */ codePtr->codeStart = p; memcpy(p, envPtr->codeStart, codeBytes); diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c index 2653630..0bc3de1 100644 --- a/generic/tclDisassemble.c +++ b/generic/tclDisassemble.c @@ -301,13 +301,14 @@ DisassembleByteCodeObj( #ifdef TCL_COMPILE_STATS Tcl_AppendPrintfToObj(bufferObj, - " Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n", - (unsigned long) codePtr->structureSize, - (unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)), + " Code %" TCL_Z_MODIFIER "u = header %" TCL_Z_MODIFIER "u+inst %d+litObj %" + TCL_Z_MODIFIER "u+exc %" TCL_Z_MODIFIER "u+aux %" TCL_Z_MODIFIER "u+cmdMap %d\n", + codePtr->structureSize, + offsetof(ByteCode, localCachePtr), codePtr->numCodeBytes, - (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)), - (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)), - (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)), + codePtr->numLitObjects * sizeof(Tcl_Obj *), + codePtr->numExceptRanges*sizeof(ExceptionRange), + codePtr->numAuxDataItems * sizeof(AuxData), codePtr->numCmdLocBytes); #endif /* TCL_COMPILE_STATS */ diff --git a/generic/tclExecute.c b/generic/tclExecute.c index 2df2611..353926c 100644 --- a/generic/tclExecute.c +++ b/generic/tclExecute.c @@ -9131,7 +9131,7 @@ PrintByteCodeInfo( #ifdef TCL_COMPILE_STATS fprintf(stdout, " Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n", (unsigned long) codePtr->structureSize, - (unsigned long) (sizeof(ByteCode)-sizeof(size_t)-sizeof(Tcl_Time)), + (unsigned long) offsetof(ByteCode, localCachePtr), codePtr->numCodeBytes, (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)), (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)), @@ -9774,7 +9774,7 @@ EvalStatsCmd( numCurrentByteCodes = statsPtr->numCompilations - statsPtr->numByteCodesFreed; currentHeaderBytes = numCurrentByteCodes - * (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)); + * offsetof(ByteCode, localCachePtr); literalMgmtBytes = sizeof(LiteralTable) + (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)) + (iPtr->literalTable.numEntries * sizeof(LiteralEntry)); diff --git a/generic/tclHash.c b/generic/tclHash.c index 606d26b..37e45e7 100644 --- a/generic/tclHash.c +++ b/generic/tclHash.c @@ -685,21 +685,16 @@ AllocArrayEntry( Tcl_HashTable *tablePtr, /* Hash table. */ void *keyPtr) /* Key to store in the hash table entry. */ { - int *array = (int *) keyPtr; - int *iPtr1, *iPtr2; Tcl_HashEntry *hPtr; - int count = tablePtr->keyType; - TCL_HASH_TYPE size = sizeof(Tcl_HashEntry) + (count*sizeof(int)) - sizeof(hPtr->key); + TCL_HASH_TYPE count = tablePtr->keyType * sizeof(int); + TCL_HASH_TYPE size = offsetof(Tcl_HashEntry, key) + count; if (size < sizeof(Tcl_HashEntry)) { size = sizeof(Tcl_HashEntry); } hPtr = (Tcl_HashEntry *)ckalloc(size); - for (iPtr1 = array, iPtr2 = hPtr->key.words; - count > 0; count--, iPtr1++, iPtr2++) { - *iPtr2 = *iPtr1; - } + memcpy(hPtr->key.string, keyPtr, count); Tcl_SetHashValue(hPtr, NULL); return hPtr; @@ -727,20 +722,9 @@ CompareArrayKeys( void *keyPtr, /* New key to compare. */ Tcl_HashEntry *hPtr) /* Existing key to compare. */ { - const int *iPtr1 = (const int *)keyPtr; - const int *iPtr2 = hPtr->key.words; - Tcl_HashTable *tablePtr = hPtr->tablePtr; - int count; + size_t count = hPtr->tablePtr->keyType * sizeof(int); - for (count = tablePtr->keyType; ; count--, iPtr1++, iPtr2++) { - if (count == 0) { - return 1; - } - if (*iPtr1 != *iPtr2) { - break; - } - } - return 0; + return !memcmp(keyPtr, hPtr->key.string, count); } /* @@ -807,7 +791,7 @@ AllocStringEntry( allocsize = sizeof(hPtr->key); } hPtr = (Tcl_HashEntry *)ckalloc(offsetof(Tcl_HashEntry, key) + allocsize); - memset(hPtr, 0, sizeof(Tcl_HashEntry) + allocsize - sizeof(hPtr->key)); + memset(hPtr, 0, offsetof(Tcl_HashEntry, key) + allocsize); memcpy(hPtr->key.string, string, size); Tcl_SetHashValue(hPtr, NULL); return hPtr; diff --git a/generic/tclInt.h b/generic/tclInt.h index eebf7ea..168ecbf 100644 --- a/generic/tclInt.h +++ b/generic/tclInt.h @@ -2358,22 +2358,34 @@ typedef struct Interp { #endif /* - * This macro is used to determine the offset needed to safely allocate any + * TCL_ALIGN is used to determine the offset needed to safely allocate any * data structure in memory. Given a starting offset or size, it "rounds up" - * or "aligns" the offset to the next 8-byte boundary so that any data - * structure can be placed at the resulting offset without fear of an - * alignment error. + * or "aligns" the offset to the next aligned (typically 8-byte) boundary so + * that any data structure can be placed at the resulting offset without fear + * of an alignment error. Note this is clamped to a minimum of 8 for API + * compatibility. * * WARNING!! DO NOT USE THIS MACRO TO ALIGN POINTERS: it will produce the - * wrong result on platforms that allocate addresses that are divisible by 4 - * or 2. Only use it for offsets or sizes. + * wrong result on platforms that allocate addresses that are divisible by a + * non-trivial factor of this alignment. Only use it for offsets or sizes. * * This macro is only used by tclCompile.c in the core (Bug 926445). It * however not be made file static, as extensions that touch bytecodes * (notably tbcload) require it. */ -#define TCL_ALIGN(x) (((int)(x) + 7) & ~7) +struct TclMaxAlignment { + char unalign[8]; + union { + long long maxAlignLongLong; + double maxAlignDouble; + void *maxAlignPointer; + } aligned; +}; +#define TCL_ALIGN_BYTES \ + offsetof(struct TclMaxAlignment, aligned) +#define TCL_ALIGN(x) \ + (((x) + (TCL_ALIGN_BYTES - 1)) & ~(TCL_ALIGN_BYTES - 1)) /* * A common panic alert when memory allocation fails. diff --git a/generic/tclProc.c b/generic/tclProc.c index e6b1372..9a3785c 100644 --- a/generic/tclProc.c +++ b/generic/tclProc.c @@ -2163,7 +2163,7 @@ TclProcCleanupProc( if (bodyPtr != NULL) { /* procPtr is stored in body's ByteCode, so ensure to reset it. */ ByteCode *codePtr; - + ByteCodeGetInternalRep(bodyPtr, &tclByteCodeType, codePtr); if (codePtr != NULL && codePtr->procPtr == procPtr) { codePtr->procPtr = NULL; diff --git a/generic/tclTest.c b/generic/tclTest.c index ed5f34b..9284969 100644 --- a/generic/tclTest.c +++ b/generic/tclTest.c @@ -61,6 +61,21 @@ static Tcl_DString delString; static Tcl_Interp *delInterp; /* + * One of the following structures exists for each command created by the + * "testcmdtoken" command. + */ + +typedef struct TestCommandTokenRef { + int id; /* Identifier for this reference. */ + Tcl_Command token; /* Tcl's token for the command. */ + struct TestCommandTokenRef *nextPtr; + /* Next in list of references. */ +} TestCommandTokenRef; + +static TestCommandTokenRef *firstCommandTokenRef = NULL; +static int nextCommandTokenRefId = 1; + +/* * One of the following structures exists for each asynchronous handler * created by the "testasync" command". */ @@ -1196,9 +1211,9 @@ TestcmdtokenCmd( int argc, /* Number of arguments. */ const char **argv) /* Argument strings. */ { - Tcl_Command token; - int *l; + TestCommandTokenRef *refPtr; char buf[30]; + int id; if (argc != 3) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], @@ -1206,24 +1221,42 @@ TestcmdtokenCmd( return TCL_ERROR; } if (strcmp(argv[1], "create") == 0) { - token = Tcl_CreateCommand(interp, argv[2], CmdProc1, + refPtr = (TestCommandTokenRef *)Tcl_Alloc(sizeof(TestCommandTokenRef)); + refPtr->token = Tcl_CreateCommand(interp, argv[2], CmdProc1, (void *) "original", NULL); - sprintf(buf, "%p", (void *)token); + refPtr->id = nextCommandTokenRefId; + nextCommandTokenRefId++; + refPtr->nextPtr = firstCommandTokenRef; + firstCommandTokenRef = refPtr; + sprintf(buf, "%d", refPtr->id); Tcl_AppendResult(interp, buf, NULL); } else if (strcmp(argv[1], "name") == 0) { Tcl_Obj *objPtr; - if (sscanf(argv[2], "%p", &l) != 1) { + if (sscanf(argv[2], "%d", &id) != 1) { + Tcl_AppendResult(interp, "bad command token \"", argv[2], + "\"", NULL); + return TCL_ERROR; + } + + for (refPtr = firstCommandTokenRef; refPtr != NULL; + refPtr = refPtr->nextPtr) { + if (refPtr->id == id) { + break; + } + } + + if (refPtr == NULL) { Tcl_AppendResult(interp, "bad command token \"", argv[2], "\"", NULL); return TCL_ERROR; } objPtr = Tcl_NewObj(); - Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr); + Tcl_GetCommandFullName(interp, refPtr->token, objPtr); Tcl_AppendElement(interp, - Tcl_GetCommandName(interp, (Tcl_Command) l)); + Tcl_GetCommandName(interp, refPtr->token)); Tcl_AppendElement(interp, Tcl_GetString(objPtr)); Tcl_DecrRefCount(objPtr); } else { |
