Object.3
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:14k
- '"
- '" Copyright (c) 1996-1997 Sun Microsystems, Inc.
- '"
- '" See the file "license.terms" for information on usage and redistribution
- '" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
- '"
- '" RCS: @(#) $Id: Object.3,v 1.6 2002/10/22 12:16:53 dkf Exp $
- '"
- .so man.macros
- .TH Tcl_Obj 3 8.1 Tcl "Tcl Library Procedures"
- .BS
- .SH NAME
- Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep - manipulate Tcl objects
- .SH SYNOPSIS
- .nf
- fB#include <tcl.h>fR
- .sp
- Tcl_Obj *
- fBTcl_NewObjfR()
- .sp
- Tcl_Obj *
- fBTcl_DuplicateObjfR(fIobjPtrfR)
- .sp
- fBTcl_IncrRefCountfR(fIobjPtrfR)
- .sp
- fBTcl_DecrRefCountfR(fIobjPtrfR)
- .sp
- int
- fBTcl_IsSharedfR(fIobjPtrfR)
- .sp
- fBTcl_InvalidateStringRepfR(fIobjPtrfR)
- .SH ARGUMENTS
- .AS Tcl_Obj *objPtr in
- .AP Tcl_Obj *objPtr in
- Points to an object;
- must have been the result of a previous call to fBTcl_NewObjfR.
- .BE
- .SH INTRODUCTION
- .PP
- This man page presents an overview of Tcl objects and how they are used.
- It also describes generic procedures for managing Tcl objects.
- These procedures are used to create and copy objects,
- and increment and decrement the count of references (pointers) to objects.
- The procedures are used in conjunction with ones
- that operate on specific types of objects such as
- fBTcl_GetIntFromObjfR and fBTcl_ListObjAppendElementfR.
- The individual procedures are described along with the data structures
- they manipulate.
- .PP
- Tcl's fIdual-portedfR objects provide a general-purpose mechanism
- for storing and exchanging Tcl values.
- They largely replace the use of strings in Tcl.
- For example, they are used to store variable values,
- command arguments, command results, and scripts.
- Tcl objects behave like strings but also hold an internal representation
- that can be manipulated more efficiently.
- For example, a Tcl list is now represented as an object
- that holds the list's string representation
- as well as an array of pointers to the objects for each list element.
- Dual-ported objects avoid most runtime type conversions.
- They also improve the speed of many operations
- since an appropriate representation is immediately available.
- The compiler itself uses Tcl objects to
- cache the instruction bytecodes resulting from compiling scripts.
- .PP
- The two representations are a cache of each other and are computed lazily.
- That is, each representation is only computed when necessary,
- it is computed from the other representation,
- and, once computed, it is saved.
- In addition, a change in one representation invalidates the other one.
- As an example, a Tcl program doing integer calculations can
- operate directly on a variable's internal machine integer
- representation without having to constantly convert
- between integers and strings.
- Only when it needs a string representing the variable's value,
- say to print it,
- will the program regenerate the string representation from the integer.
- Although objects contain an internal representation,
- their semantics are defined in terms of strings:
- an up-to-date string can always be obtained,
- and any change to the object will be reflected in that string
- when the object's string representation is fetched.
- Because of this representation invalidation and regeneration,
- it is dangerous for extension writers to access
- fBTcl_ObjfR fields directly.
- It is better to access Tcl_Obj information using
- procedures like fBTcl_GetStringFromObjfR and fBTcl_GetStringfR.
- .PP
- Objects are allocated on the heap
- and are referenced using a pointer to their fBTcl_ObjfR structure.
- Objects are shared as much as possible.
- This significantly reduces storage requirements
- because some objects such as long lists are very large.
- Also, most Tcl values are only read and never modified.
- This is especially true for procedure arguments,
- which can be shared between the caller and the called procedure.
- Assignment and argument binding is done by
- simply assigning a pointer to the value.
- Reference counting is used to determine when it is safe to
- reclaim an object's storage.
- .PP
- Tcl objects are typed.
- An object's internal representation is controlled by its type.
- Seven types are predefined in the Tcl core
- including integer, double, list, and bytecode.
- Extension writers can extend the set of types
- by using the procedure fBTcl_RegisterObjTypefR .
- .SH "THE TCL_OBJ STRUCTURE"
- .PP
- Each Tcl object is represented by a fBTcl_ObjfR structure
- which is defined as follows.
- .CS
- typedef struct Tcl_Obj {
- int fIrefCountfR;
- char *fIbytesfR;
- int fIlengthfR;
- Tcl_ObjType *fItypePtrfR;
- union {
- long fIlongValuefR;
- double fIdoubleValuefR;
- VOID *fIotherValuePtrfR;
- struct {
- VOID *fIptr1fR;
- VOID *fIptr2fR;
- } fItwoPtrValuefR;
- } fIinternalRepfR;
- } Tcl_Obj;
- .CE
- The fIbytesfR and the fIlengthfR members together hold
- .VS 8.1
- an object's UTF-8 string representation,
- which is a fIcounted stringfR not containing null bytes (UTF-8 null
- characters should be encoded as a two byte sequence: 192, 128.)
- fIbytesfR points to the first byte of the string representation.
- The fIlengthfR member gives the number of bytes.
- The byte array must always have a null byte after the last data byte,
- at offset fIlengthfR;
- this allows string representations
- to be treated as conventional null-terminated C strings.
- .VE 8.1
- C programs use fBTcl_GetStringFromObjfR and fBTcl_GetStringfR to get
- an object's string representation.
- If fIbytesfR is NULL,
- the string representation is invalid.
- .PP
- An object's type manages its internal representation.
- The member fItypePtrfR points to the Tcl_ObjType structure
- that describes the type.
- If fItypePtrfR is NULL,
- the internal representation is invalid.
- .PP
- The fIinternalRepfR union member holds
- an object's internal representation.
- This is either a (long) integer, a double-precision floating point number,
- a pointer to a value containing additional information
- needed by the object's type to represent the object,
- or two arbitrary pointers.
- .PP
- The fIrefCountfR member is used to tell when it is safe to free
- an object's storage.
- It holds the count of active references to the object.
- Maintaining the correct reference count is a key responsibility
- of extension writers.
- Reference counting is discussed below
- in the section fBSTORAGE MANAGEMENT OF OBJECTSfR.
- .PP
- Although extension writers can directly access
- the members of a Tcl_Obj structure,
- it is much better to use the appropriate procedures and macros.
- For example, extension writers should never
- read or update fIrefCountfR directly;
- they should use macros such as
- fBTcl_IncrRefCountfR and fBTcl_IsSharedfR instead.
- .PP
- A key property of Tcl objects is that they hold two representations.
- An object typically starts out containing only a string representation:
- it is untyped and has a NULL fItypePtrfR.
- An object containing an empty string or a copy of a specified string
- is created using fBTcl_NewObjfR or fBTcl_NewStringObjfR respectively.
- An object's string value is gotten with
- fBTcl_GetStringFromObjfR or fBTcl_GetStringfR
- and changed with fBTcl_SetStringObjfR.
- If the object is later passed to a procedure like fBTcl_GetIntFromObjfR
- that requires a specific internal representation,
- the procedure will create one and set the object's fItypePtrfR.
- The internal representation is computed from the string representation.
- An object's two representations are duals of each other:
- changes made to one are reflected in the other.
- For example, fBTcl_ListObjReplacefR will modify an object's
- internal representation and the next call to fBTcl_GetStringFromObjfR
- or fBTcl_GetStringfR will reflect that change.
- .PP
- Representations are recomputed lazily for efficiency.
- A change to one representation made by a procedure
- such as fBTcl_ListObjReplacefR is not reflected immediately
- in the other representation.
- Instead, the other representation is marked invalid
- so that it is only regenerated if it is needed later.
- Most C programmers never have to be concerned with how this is done
- and simply use procedures such as fBTcl_GetBooleanFromObjfR or
- fBTcl_ListObjIndexfR.
- Programmers that implement their own object types
- must check for invalid representations
- and mark representations invalid when necessary.
- The procedure fBTcl_InvalidateStringRepfR is used
- to mark an object's string representation invalid and to
- free any storage associated with the old string representation.
- .PP
- Objects usually remain one type over their life,
- but occasionally an object must be converted from one type to another.
- For example, a C program might build up a string in an object
- with repeated calls to fBTcl_AppendToObjfR,
- and then call fBTcl_ListObjIndexfR to extract a list element from
- the object.
- The same object holding the same string value
- can have several different internal representations
- at different times.
- Extension writers can also force an object to be converted from one type
- to another using the fBTcl_ConvertToTypefR procedure.
- Only programmers that create new object types need to be concerned
- about how this is done.
- A procedure defined as part of the object type's implementation
- creates a new internal representation for an object
- and changes its fItypePtrfR.
- See the man page for fBTcl_RegisterObjTypefR
- to see how to create a new object type.
- .SH "EXAMPLE OF THE LIFETIME OF AN OBJECT"
- .PP
- As an example of the lifetime of an object,
- consider the following sequence of commands:
- .CS
- fBset x 123fR
- .CE
- This assigns to fIxfR an untyped object whose
- fIbytesfR member points to fB123fR and fIlengthfR member contains 3.
- The object's fItypePtrfR member is NULL.
- .CS
- fBputs "x is $x"fR
- .CE
- fIxfR's string representation is valid (since fIbytesfR is non-NULL)
- and is fetched for the command.
- .CS
- fBincr xfR
- .CE
- The fBincrfR command first gets an integer from fIxfR's object
- by calling fBTcl_GetIntFromObjfR.
- This procedure checks whether the object is already an integer object.
- Since it is not, it converts the object
- by setting the object's fIinternalRep.longValuefR member
- to the integer fB123fR
- and setting the object's fItypePtrfR
- to point to the integer Tcl_ObjType structure.
- Both representations are now valid.
- fBincrfR increments the object's integer internal representation
- then invalidates its string representation
- (by calling fBTcl_InvalidateStringRepfR)
- since the string representation
- no longer corresponds to the internal representation.
- .CS
- fBputs "x is now $x"fR
- .CE
- The string representation of fIxfR's object is needed
- and is recomputed.
- The string representation is now fB124fR.
- and both representations are again valid.
- .SH "STORAGE MANAGEMENT OF OBJECTS"
- .PP
- Tcl objects are allocated on the heap and are shared as much as possible
- to reduce storage requirements.
- Reference counting is used to determine when an object is
- no longer needed and can safely be freed.
- An object just created by fBTcl_NewObjfR or fBTcl_NewStringObjfR
- has fIrefCountfR 0.
- The macro fBTcl_IncrRefCountfR increments the reference count
- when a new reference to the object is created.
- The macro fBTcl_DecrRefCountfR decrements the count
- when a reference is no longer needed and,
- if the object's reference count drops to zero, frees its storage.
- An object shared by different code or data structures has
- fIrefCountfR greater than 1.
- Incrementing an object's reference count ensures that
- it won't be freed too early or have its value change accidently.
- .PP
- As an example, the bytecode interpreter shares argument objects
- between calling and called Tcl procedures to avoid having to copy objects.
- It assigns the call's argument objects to the procedure's
- formal parameter variables.
- In doing so, it calls fBTcl_IncrRefCountfR to increment
- the reference count of each argument since there is now a new
- reference to it from the formal parameter.
- When the called procedure returns,
- the interpreter calls fBTcl_DecrRefCountfR to decrement
- each argument's reference count.
- When an object's reference count drops less than or equal to zero,
- fBTcl_DecrRefCountfR reclaims its storage.
- Most command procedures do not have to be concerned about
- reference counting since they use an object's value immediately
- and don't retain a pointer to the object after they return.
- However, if they do retain a pointer to an object in a data structure,
- they must be careful to increment its reference count
- since the retained pointer is a new reference.
- .PP
- Command procedures that directly modify objects
- such as those for fBlappendfR and fBlinsertfR must be careful to
- copy a shared object before changing it.
- They must first check whether the object is shared
- by calling fBTcl_IsSharedfR.
- If the object is shared they must copy the object
- by using fBTcl_DuplicateObjfR;
- this returns a new duplicate of the original object
- that has fIrefCountfR 0.
- If the object is not shared,
- the command procedure "owns" the object and can safely modify it directly.
- For example, the following code appears in the command procedure
- that implements fBlinsertfR.
- This procedure modifies the list object passed to it in fIobjv[1]fR
- by inserting fIobjc-3fR new elements before fIindexfR.
- .CS
- listPtr = objv[1];
- if (Tcl_IsShared(listPtr)) {
- listPtr = Tcl_DuplicateObj(listPtr);
- }
- result = Tcl_ListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]));
- .CE
- As another example, fBincrfR's command procedure
- must check whether the variable's object is shared before
- incrementing the integer in its internal representation.
- If it is shared, it needs to duplicate the object
- in order to avoid accidently changing values in other data structures.
- .SH "SEE ALSO"
- Tcl_ConvertToType, Tcl_GetIntFromObj, Tcl_ListObjAppendElement, Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_RegisterObjType
- .SH KEYWORDS
- internal representation, object, object creation, object type, reference counting, string representation, type conversion