summaryrefslogtreecommitdiffstats
path: root/doc/ObjectType.3
diff options
context:
space:
mode:
Diffstat (limited to 'doc/ObjectType.3')
-rw-r--r--doc/ObjectType.3147
1 files changed, 100 insertions, 47 deletions
diff --git a/doc/ObjectType.3 b/doc/ObjectType.3
index cc84fd1..974ea6c 100644
--- a/doc/ObjectType.3
+++ b/doc/ObjectType.3
@@ -24,12 +24,12 @@ int
int
\fBTcl_ConvertToType\fR(\fIinterp, objPtr, typePtr\fR)
.SH ARGUMENTS
-.AS Tcl_ObjType *typeName in
+.AS "const char" *typeName
.AP Tcl_ObjType *typePtr in
Points to the structure containing information about the Tcl object type.
This storage must live forever,
typically by being statically allocated.
-.AP "CONST char" *typeName in
+.AP "const char" *typeName in
The name of a Tcl object type that \fBTcl_GetObjType\fR should look up.
.AP Tcl_Interp *interp in
Interpreter to use for error reporting.
@@ -43,12 +43,14 @@ must have been the result of a previous call to \fBTcl_NewObj\fR.
.SH DESCRIPTION
.PP
The procedures in this man page manage Tcl object types.
-The are used to register new object types,
-look up types,
+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
@@ -59,11 +61,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;
@@ -73,7 +75,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
@@ -81,118 +84,168 @@ 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 \fItypePtr->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
+structure 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
typedef struct Tcl_ObjType {
- char *\fIname\fR;
- Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
- Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
- Tcl_UpdateStringProc *\fIupdateStringProc\fR;
- Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
+ char *\fIname\fR;
+ Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
+ Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
+ Tcl_UpdateStringProc *\fIupdateStringProc\fR;
+ Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
} Tcl_ObjType;
.CE
+.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"
.PP
The \fIsetFromAnyProc\fR member contains the address of a function
called to create a valid internal representation
from an object's string representation.
+.PP
.CS
-typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *\fIinterp\fR, Tcl_Obj *\fIobjPtr\fR);
+typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *\fIinterp\fR,
+ Tcl_Obj *\fIobjPtr\fR);
.CE
-If an internal representation can't be created from the string,
+.PP
+If an internal representation cannot be created from the string,
it returns \fBTCL_ERROR\fR and puts a message
describing the error in the result object for \fIinterp\fR
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 builtin 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
called to create a valid string representation
from an object's internal representation.
+.PP
.CS
typedef void (Tcl_UpdateStringProc) (Tcl_Obj *\fIobjPtr\fR);
.CE
+.PP
\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 builtin 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
called to copy an internal representation from one object to another.
+.PP
.CS
-typedef void (Tcl_DupInternalRepProc) (Tcl_Obj *\fIsrcPtr\fR, Tcl_Obj *\fIdupPtr\fR);
+typedef void (Tcl_DupInternalRepProc) (Tcl_Obj *\fIsrcPtr\fR,
+ Tcl_Obj *\fIdupPtr\fR);
.CE
+.PP
\fIdupPtr\fR's internal representation is made a copy of \fIsrcPtr\fR's
internal representation.
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 builtin 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
that is called when an object is freed.
+.PP
.CS
typedef void (Tcl_FreeInternalRepProc) (Tcl_Obj *\fIobjPtr\fR);
.CE
+.PP
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 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
internal representation, object, object type, string representation, type conversion