From d8e2dd0ef8a84e1820e1788874d1a88063ab4e26 Mon Sep 17 00:00:00 2001 From: dgp Date: Mon, 30 Jun 2008 02:34:05 +0000 Subject: * doc/ObjectType.3: Updated documentation of the Tcl_ObjType struct to match expectations of Tcl 8.5 [Bug 1917650]. --- ChangeLog | 3 ++ doc/ObjectType.3 | 110 +++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/ChangeLog b/ChangeLog index b512045..f3123f1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2008-06-29 Don Porter + * doc/ObjectType.3: Updated documentation of the Tcl_ObjType + struct to match expectations of Tcl 8.5 [Bug 1917650]. + * generic/tclPathObj.c: Plug memory leak in [Bug 1999176] fix. Thanks Rolf Ade for detecting. diff --git a/doc/ObjectType.3 b/doc/ObjectType.3 index f7bdb9f..cf88fd0 100644 --- a/doc/ObjectType.3 +++ b/doc/ObjectType.3 @@ -4,7 +4,7 @@ '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. '\" -'\" RCS: @(#) $Id: ObjectType.3,v 1.16 2007/12/13 15:22:31 dgp Exp $ +'\" RCS: @(#) $Id: ObjectType.3,v 1.16.2.1 2008/06/30 02:34:07 dgp Exp $ '\" .so man.macros .TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures" @@ -49,7 +49,10 @@ They are used to register new object types, look up types, and force conversions from one type to another. .PP \fBTcl_RegisterObjType\fR registers a new Tcl object type -in the table of all object types supported by Tcl. +in the table of all object types that \fBTcl_GetObjType\fR +can look up by name. There are other object types supported by Tcl +as well, which Tcl chooses not to register. Extensions can likewise +choose to register the object types they create or not. The argument \fItypePtr\fR points to a Tcl_ObjType structure that describes the new type by giving its name and by supplying pointers to four procedures @@ -60,11 +63,11 @@ it is replaced with the new type. The Tcl_ObjType structure is described in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below. .PP -\fBTcl_GetObjType\fR returns a pointer to the Tcl_ObjType +\fBTcl_GetObjType\fR returns a pointer to the registered Tcl_ObjType with name \fItypeName\fR. It returns NULL if no type with that name is registered. .PP -\fBTcl_AppendAllObjTypes\fR appends the name of each object type +\fBTcl_AppendAllObjTypes\fR appends the name of each registered object type as a list element onto the Tcl object referenced by \fIobjPtr\fR. The return value is \fBTCL_OK\fR unless there was an error converting \fIobjPtr\fR to a list object; @@ -74,7 +77,8 @@ in that case \fBTCL_ERROR\fR is returned. if possible. It creates a new internal representation for \fIobjPtr\fR appropriate for the target type \fItypePtr\fR -and sets its \fItypePtr\fR member to that type. +and sets its \fItypePtr\fR member as determined by calling the +\fItypePtr->setFromAnyProc\fR routine. Any internal representation for \fIobjPtr\fR's old type is freed. If an error occurs during conversion, it returns \fBTCL_ERROR\fR and leaves an error message in the result object for \fIinterp\fR @@ -82,12 +86,23 @@ unless \fIinterp\fR is NULL. Otherwise, it returns \fBTCL_OK\fR. Passing a NULL \fIinterp\fR allows this procedure to be used as a test whether the conversion can be done (and in fact was done). +.VS 8.5 +.PP +In many cases, the \fItypePtt->setFromAnyProc\fR routine will +set \fIobjPtr->typePtr\fR to the argument value \fItypePtr\fR, +but that is no longer guaranteed. The \fIsetFromAnyProc\fR is +free to set the internal representation for \fIobjPtr\fR to make +use of another related Tcl_ObjType, if it sees fit. +.VE 8.5 .SH "THE TCL_OBJTYPE STRUCTURE" .PP Extension writers can define new object types by defining four -procedures, -initializing a Tcl_ObjType structure to describe the type, -and calling \fBTcl_RegisterObjType\fR. +procedures and +initializing a Tcl_ObjType structure to describe the type. +Extension writers may also pass a pointer to their Tcl_ObjType +structire to \fBTcl_RegisterObjType\fR if they wish to permit +other extensions to look up their Tcl_ObjType by name with +the \fBTcl_GetObjType\fR routine. The \fBTcl_ObjType\fR structure is defined as follows: .PP .CS @@ -102,8 +117,9 @@ typedef struct Tcl_ObjType { .SS "THE NAME FIELD" .PP The \fIname\fR member describes the name of the type, e.g. \fBint\fR. -Extension writers can look up an object type using its name -with the \fBTcl_GetObjType\fR procedure. +When a type is registered, this is the name used by callers +of \fBTcl_GetObjType\fR to lookup the type. For unregistered +types, the \fIname\fR field is primarily of value for debugging. The remaining four members are pointers to procedures called by the generic Tcl object code: .SS "THE SETFROMANYPROC FIELD" @@ -124,22 +140,32 @@ unless \fIinterp\fR is NULL. If \fIsetFromAnyProc\fR is successful, it stores the new internal representation, sets \fIobjPtr\fR's \fItypePtr\fR member to point to -\fIsetFromAnyProc\fR's \fBTcl_ObjType\fR, and returns \fBTCL_OK\fR. +the \fBTcl_ObjType\fR struct corresponding to the new +internal representation, and returns \fBTCL_OK\fR. Before setting the new internal representation, the \fIsetFromAnyProc\fR must free any internal representation of \fIobjPtr\fR's old type; it does this by calling the old type's \fIfreeIntRepProc\fR if it is not NULL. -As an example, the \fIsetFromAnyProc\fR for the built-in Tcl integer type +.PP +As an example, the \fIsetFromAnyProc\fR for the built-in Tcl list type gets an up-to-date string representation for \fIobjPtr\fR by calling \fBTcl_GetStringFromObj\fR. -It parses the string to obtain an integer and, -if this succeeds, -stores the integer in \fIobjPtr\fR's internal representation -and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the integer type's +It parses the string to verify it is in a valid list format and +to obtain each element value in the list, and, if this succeeds, +stores the list elements in \fIobjPtr\fR's internal representation +and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the list type's Tcl_ObjType structure. +.PP Do not release \fIobjPtr\fR's old internal representation unless you replace it with a new one or reset the \fItypePtr\fR member to NULL. +.PP +The \fIsetFromAnyProc\fR member may be set to NULL, if the routines +making use of the internal representation have no need to derive that +internal representation from an arbitrary string value. However, in +this case, passing a pointer to the type to Tcl_ConvertToType() will +lead to a panic, so to avoid this possibility, the type +should \fInot\fR be registered. .SS "THE UPDATESTRINGPROC FIELD" .PP The \fIupdateStringProc\fR member contains the address of a function @@ -153,17 +179,27 @@ typedef void (Tcl_UpdateStringProc) (Tcl_Obj *\fIobjPtr\fR); \fIobjPtr\fR's \fIbytes\fR member is always NULL when it is called. It must always set \fIbytes\fR non-NULL before returning. We require the string representation's byte array -to have a null after the last byte, at offset \fIlength\fR; -this allows string representations that do not contain null bytes +to have a null after the last byte, at offset \fIlength\fR, +and to have no null bytes before that; this allows string representations to be treated as conventional null character-terminated C strings. +These restrictions are easily met by using Tcl's internal UTF encoding +for the string representation, same as one would do for other +Tcl routines accepting string values as arguments. Storage for the byte array must be allocated in the heap by \fBTcl_Alloc\fR or \fBckalloc\fR. Note that \fIupdateStringProc\fRs must allocate enough storage for the string's bytes and the terminating null byte. -The \fIupdateStringProc\fR for Tcl's built-in list type, for example, -builds an array of strings for each element object -and then calls \fBTcl_Merge\fR -to construct a string with proper Tcl list structure. -It stores this string as the list object's string representation. +.PP +The \fIupdateStringProc\fR for Tcl's built-in double type, for example, +calls Tcl_PrintDouble to write to a buffer of size TCL_DOUBLE_SPACE, +then allocates and copies the string representation to just enough +space to hold it. A pointer to the allocated space is stored in +the \fIbytes\fR member. +.PP +The \fIupdateStringProc\fR member may be set to NULL, if the routines +making use of the internal representation are written so that the +string representation is never invalidated. Failure to meet this +obligation will lead to panics or crashes when \fBTcl_GetStringFromObj\fR +or other similar routines ask for the string representation. .SS "THE DUPINTREPPROC FIELD" .PP The \fIdupIntRepProc\fR member contains the address of a function @@ -180,12 +216,12 @@ Before the call, \fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not. \fIsrcPtr\fR's object type determines what copying its internal representation means. +.PP For example, the \fIdupIntRepProc\fR for the Tcl integer type simply copies an integer. -The built-in list type's \fIdupIntRepProc\fR -allocates a new array that points at the original element objects; -the elements are shared between the two lists -(and their reference counts are incremented to reflect the new references). +The built-in list type's \fIdupIntRepProc\fR uses a far more +sophisticated scheme to continue sharing storage as much as it +reasonably can. .SS "THE FREEINTREPPROC FIELD" .PP The \fIfreeIntRepProc\fR member contains the address of a function @@ -198,17 +234,19 @@ typedef void (Tcl_FreeInternalRepProc) (Tcl_Obj *\fIobjPtr\fR); The \fIfreeIntRepProc\fR function can deallocate the storage for the object's internal representation and do other type-specific processing necessary when an object is freed. -For example, Tcl list objects have an \fIinternalRep.otherValuePtr\fR -that points to an array of pointers to each element in the list. -The list type's \fIfreeIntRepProc\fR decrements -the reference count for each element object -(since the list will no longer refer to those objects), -then deallocates the storage for the array of pointers. +.PP +For example, the list type's \fIfreeIntRepProc\fR respects +the storage sharing scheme established by the \fIdupIntRepProc\fR +so that it only frees storage when the last object sharing it +is being freed. +.PP The \fIfreeIntRepProc\fR member can be set to NULL to indicate that the internal representation does not require freeing. -The \fIfreeIntRepProc\fR implementation should not access the -\fIbytes\fR member of the object, as this may potentially have already -been deleted. +The \fIfreeIntRepProc\fR implementation must not access the +\fIbytes\fR member of the object, since Tcl makes its own internal +uses of that field during object deletion. The defined tasks for +the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR +member. .SH "SEE ALSO" Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount .SH KEYWORDS -- cgit v0.12