Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
Tcl_Obj(3)		     Tcl Library Procedures		      Tcl_Obj(3)

________________________________________________________________________________

NAME
     Tcl_NewObj,  Tcl_DuplicateObj,  Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_Is-
     Shared, Tcl_InvalidateStringRep - manipulate Tcl values

SYNOPSIS
     #include <tcl.h>

     Tcl_Obj *
     Tcl_NewObj()

     Tcl_Obj *
     Tcl_DuplicateObj(objPtr)

     Tcl_IncrRefCount(objPtr)

     Tcl_DecrRefCount(objPtr)

     int
     Tcl_IsShared(objPtr)

     Tcl_InvalidateStringRep(objPtr)

ARGUMENTS
     Tcl_Obj *objPtr (in)	   Points to a value; must have been the  result
				   of a previous call to Tcl_NewObj.
________________________________________________________________________________

INTRODUCTION
     This  man page presents an overview of Tcl values (called Tcl_Objs for his-
     torical reasons) and how they are used.  It also describes  generic  proce-
     dures  for  managing  Tcl	values.  These procedures are used to create and
     copy values, and increment and decrement the count of references (pointers)
     to values.  The procedures are used in conjunction with ones  that  operate
     on specific types of values such as Tcl_GetIntFromObj and Tcl_ListObjAppen-
     dElement.	 The  individual  procedures  are  described along with the data
     structures they manipulate.

     Tcl's dual-ported values 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 values behave like strings but also hold
     an internal representation that can be manipulated more  efficiently.   For
     example,  a  Tcl  list  is now represented as a value that holds the list's
     string representation as well as an array of pointers  to	the  values  for
     each list element.  Dual-ported values avoid most runtime type conversions.
     They  also improve the speed of many operations since an appropriate repre-
     sentation is immediately available.  The compiler itself uses Tcl values to
     cache the instruction bytecodes resulting from compiling scripts.

     The two representations are a cache of each other and are computed  lazily.
     That  is,	each  representation is only computed when necessary, it is com-
     puted 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  con-
     stantly  convert between integers and strings.  Only when it needs a string
     representing the variable's value, say to print it, will the program regen-
     erate the string representation from the integer.	Although values  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
     value will be reflected in that string when the value's string  representa-
     tion is fetched.  Because of this representation invalidation and regenera-
     tion,  it	is  dangerous for extension writers to access Tcl_Obj fields di-
     rectly.  It is better to access Tcl_Obj information using	procedures  like
     Tcl_GetStringFromObj and Tcl_GetString.

     Values  are  allocated  on  the  heap and are referenced using a pointer to
     their Tcl_Obj structure.  Values are shared as much as possible.  This sig-
     nificantly reduces storage requirements because some values  such	as  long
     lists  are very large.  Also, most Tcl values are only read and never modi-
     fied.  This is especially true for procedure arguments, which can be shared
     between the caller and the called procedure.  Assignment and argument bind-
     ing is done by simply assigning a pointer to the value.  Reference counting
     is used to determine when it is safe to reclaim a value's storage.

     Tcl values are typed.  A value's internal representation is  controlled  by
     its  type.  Several types are predefined in the Tcl core including integer,
     double, list, and bytecode.  Extension writers can extend the set of  types
     by defining their own Tcl_ObjType structs.

THE TCL_OBJ STRUCTURE
     Each  Tcl	value  is represented by a Tcl_Obj structure which is defined as
     follows.

	    typedef struct Tcl_Obj {
		int refCount;
		char *bytes;
		int length;
		const Tcl_ObjType *typePtr;
		union {
		    long longValue;
		    double doubleValue;
		    void *otherValuePtr;
		    Tcl_WideInt wideValue;
		    struct {
			void *ptr1;
			void *ptr2;
		    } twoPtrValue;
		    struct {
			void *ptr;
			unsigned long value;
		    } ptrAndLongRep;
		} internalRep;
	    } Tcl_Obj;

     The bytes and the length members together hold a value's UTF-8 string  rep-
     resentation,  which  is  a  counted string not containing null bytes (UTF-8
     null characters should be encoded as a two byte sequence: 192, 128.)  bytes
     points to the first byte of the string representation.  The  length  member
     gives the number of bytes.  The byte array must always have a null byte af-
     ter  the  last  data byte, at offset length; this allows string representa-
     tions to be treated as conventional null-terminated C strings.  C	programs
     use  Tcl_GetStringFromObj	and Tcl_GetString to get a value's string repre-
     sentation.  If bytes is NULL, the string representation is invalid.

     A value's type manages its internal  representation.   The  member  typePtr
     points to the Tcl_ObjType structure that describes the type.  If typePtr is
     NULL, the internal representation is invalid.

     The internalRep union member holds a value'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  value's
     type to represent the value, a Tcl_WideInt integer, two arbitrary pointers,
     or a pair made up of an unsigned long integer and a pointer.

     The refCount member is used to tell when it is safe to free a value's stor-
     age.   It	holds  the count of active references to the value.  Maintaining
     the correct reference count is a key responsibility of  extension	writers.
     Reference	counting is discussed below in the section STORAGE MANAGEMENT OF
     VALUES.

     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  refCount  di-
     rectly;  they  should  use macros such as Tcl_IncrRefCount and Tcl_IsShared
     instead.

     A key property of Tcl values is that  they  hold  two  representations.   A
     value  typically  starts out containing only a string representation: it is
     untyped and has a NULL typePtr.  A value containing an empty  string  or  a
     copy  of a specified string is created using Tcl_NewObj or Tcl_NewStringObj
     respectively.  A value's string value is gotten  with  Tcl_GetStringFromObj
     or  Tcl_GetString and changed with Tcl_SetStringObj.  If the value is later
     passed to a procedure like Tcl_GetIntFromObj that requires a  specific  in-
     ternal  representation,  the  procedure will create one and set the value's
     typePtr.  The internal representation is computed from the string represen-
     tation.  A value's two representations are duals  of  each  other:  changes
     made  to  one  are reflected in the other.  For example, Tcl_ListObjReplace
     will modify a value's internal representation and the next call to Tcl_Get-
     StringFromObj or Tcl_GetString will reflect that change.

     Representations are recomputed lazily for efficiency.  A change to one rep-
     resentation made by a procedure such as Tcl_ListObjReplace 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  Tcl_GetBooleanFromObj  or  Tcl_ListObjIndex.
     Programmers  that	implement  their  own value types must check for invalid
     representations and mark representations invalid when necessary.  The  pro-
     cedure Tcl_InvalidateStringRep is used to mark a value's string representa-
     tion  invalid and to free any storage associated with the old string repre-
     sentation.

     Values usually remain one type over their life, but  occasionally	a  value
     must be converted from one type to another.  For example, a C program might
     build  up	a  string in a value with repeated calls to Tcl_AppendToObj, and
     then call Tcl_ListObjIndex to extract a list element from the  value.   The
     same  value holding the same string value can have several different inter-
     nal representations at different times.  Extension writers can also force a
     value to be converted from one type to another using the  Tcl_ConvertToType
     procedure.   Only	programmers  that create new value types need to be con-
     cerned about how this is done.  A procedure defined as part  of  the  value
     type's implementation creates a new internal representation for a value and
     changes  its  typePtr.  See the man page for Tcl_RegisterObjType to see how
     to create a new value type.

EXAMPLE OF THE LIFETIME OF A VALUE
     As an example of the lifetime of a value, consider the  following	sequence
     of commands:

	    set x 123

     This  assigns  to	x  an untyped value whose bytes member points to 123 and
     length member contains 3.	The value's typePtr member is NULL.

	    puts "x is $x"

     x's string representation is valid (since bytes is non-NULL) and is fetched
     for the command.

	    incr x

     The incr command first gets an integer from x's value by  calling	Tcl_Get-
     IntFromObj.   This procedure checks whether the value is already an integer
     value.  Since it is not, it converts the value by setting the  value's  in-
     ternal representation to the integer 123 and setting the value's typePtr to
     point  to	the integer Tcl_ObjType structure.  Both representations are now
     valid.  incr increments the value's integer  internal  representation  then
     invalidates  its string representation (by calling Tcl_InvalidateStringRep)
     since the string representation no longer corresponds to the internal  rep-
     resentation.

	    puts "x is now $x"

     The  string  representation  of x's value is needed and is recomputed.  The
     string representation is now 124 and both representations are again valid.

STORAGE MANAGEMENT OF VALUES
     Tcl values are allocated on the heap and are shared as much as possible  to
     reduce  storage requirements.  Reference counting is used to determine when
     a value is no longer needed and can safely be freed.  A value just  created
     by  Tcl_NewObj  or Tcl_NewStringObj has refCount 0.  The macro Tcl_IncrRef-
     Count increments the reference count when a new reference to the  value  is
     created.	The macro Tcl_DecrRefCount decrements the count when a reference
     is no longer needed and, if the value's  reference  count	drops  to  zero,
     frees its storage.  A value shared by different code or data structures has
     refCount  greater	than  1.  Incrementing a value's reference count ensures
     that it will not be freed too early or have its value change accidentally.

     As an example, the bytecode  interpreter  shares  argument  values  between
     calling  and  called Tcl procedures to avoid having to copy values.  It as-
     signs the call's argument values to the procedure's formal parameter  vari-
     ables.   In  doing so, it calls Tcl_IncrRefCount 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
     Tcl_DecrRefCount  to  decrement  each  argument's	reference count.  When a
     value's reference count drops less than or equal to zero,	Tcl_DecrRefCount
     reclaims  its storage.  Most command procedures do not have to be concerned
     about reference counting since they use a value's value immediately and  do
     not  retain  a pointer to the value after they return.  However, if they do
     retain a pointer to a value in a data structure, they must  be  careful  to
     increment	its  reference	count since the retained pointer is a new refer-
     ence.

     Command procedures that directly modify values such as  those  for  lappend
     and  linsert  must  be  careful  to copy a shared value before changing it.
     They must first check whether the value is shared by calling  Tcl_IsShared.
     If  the value is shared they must copy the value by using Tcl_DuplicateObj;
     this returns a new duplicate of the original value that has refCount 0.  If
     the value is not shared, the command procedure "owns"  the  value	and  can
     safely  modify it directly.  For example, the following code appears in the
     command procedure that implements linsert.   This	procedure  modifies  the
     list  value passed to it in objv[1] by inserting objc-3 new elements before
     index.

	    listPtr = objv[1];
	    if (Tcl_IsShared(listPtr)) {
		listPtr = Tcl_DuplicateObj(listPtr);
	    }
	    result = Tcl_ListObjReplace(interp, listPtr, index, 0,
		    (objc-3), &(objv[3]));

     As another example, incr's command procedure must check whether  the  vari-
     able's value is shared before incrementing the integer in its internal rep-
     resentation.   If it is shared, it needs to duplicate the value in order to
     avoid accidentally changing values in other data structures.

SEE ALSO
     Tcl_ConvertToType(3),  Tcl_GetIntFromObj(3),   Tcl_ListObjAppendElement(3),
     Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)

KEYWORDS
     internal  representation,	value,	value  creation,  value  type, reference
     counting, string representation, type conversion

Tcl				       8.5			      Tcl_Obj(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=Tcl_IsShared.tcl86&sektion=3&manpath=FreeBSD+Ports+15.1.quarterly>

home | help