Seth Woolley's Man Viewer

Object(3) - Tcl_DecrRefCount, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_InvalidateStringRep, Tcl_IsShared, Tcl_NewObj, Tcl_DecrRefCount, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_InvalidateStringRep, Tcl_IsShared, Tcl_NewObj - manipulate Tcl objects - man 3 Object

([section] manual, -k keyword, -K [section] search, -f whatis)
man plain no title

Tcl_Obj(3)                  Tcl Library Procedures                  Tcl_Obj(3)



NAME
       Tcl_NewObj,   Tcl_DuplicateObj,   Tcl_IncrRefCount,   Tcl_DecrRefCount,
       Tcl_IsShared, Tcl_InvalidateStringRep - manipulate Tcl objects

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
       Points to an object; must have been the result of a  previous  call  to
       Tcl_NewObj.


INTRODUCTION
       This  man(1,5,7)  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  proce-
       dures  are used in(1,8) conjunction with ones that operate on specific types
       of objects such as Tcl_GetIntFromObj and Tcl_ListObjAppendElement.  The
       individual procedures are described along with the data structures they
       manipulate.

       Tcl's dual-ported objects provide a general-purpose mechanism for stor-
       ing and exchanging Tcl values.  They largely replace the use of strings
       in(1,8) 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  manipu-
       lated  more efficiently.  For example, a Tcl list is now represented as
       an object that holds the list's string(3,n) 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 immedi-
       ately available.  The compiler itself uses Tcl  objects  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 computed from the other representation, and, once computed, it is
       saved.  In addition, a change in(1,8)  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  representa-
       tion without having to constantly convert between integers and strings.
       Only when it needs a string(3,n) representing the variable's value,  say  to
       print  it,  will  the program regenerate the string(3,n) representation from
       the integer.  Although  objects  contain  an  internal  representation,
       their  semantics  are defined in(1,8) terms of strings: an up-to-date string(3,n)
       can always be obtained, and any change to the object will be  reflected
       in(1,8)  that  string(3,n)  when  the  object's string(3,n) representation is fetched.
       Because of this representation invalidation  and  regeneration,  it  is
       dangerous  for extension writers to access(2,5) Tcl_Obj fields directly.  It
       is better to access(2,5) Tcl_Obj information using procedures like  Tcl_Get-
       StringFromObj and Tcl_GetString.

       Objects are allocated on the heap and are referenced using a pointer to
       their Tcl_Obj 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(2,n,1 builtins)  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.

       Tcl  objects  are  typed.   An object's internal representation is con-
       trolled by its type.  Seven  types  are  predefined  in(1,8)  the  Tcl  core
       including  integer,  double, list, and bytecode.  Extension writers can
       extend the set(7,n,1 builtins) of types by using the procedure Tcl_RegisterObjType .


THE TCL_OBJ STRUCTURE
       Each Tcl object is represented by a Tcl_Obj structure which is  defined
       as  follows.   typedef  struct  Tcl_Obj  {      int refCount;      char
       *bytes;       int  length;       Tcl_ObjType  *typePtr;       union   {
                 long  longValue;           double doubleValue;           VOID
       *otherValuePtr;             struct   {                   VOID    *ptr1;
                      VOID *ptr2;           } twoPtrValue;      } internalRep;
       } Tcl_Obj; The bytes and the length members together hold  an  object's
       UTF-8  string(3,n)  representation, which is a counted string(3,n) 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(3,n) rep-
       resentation.  The length member gives the number of  bytes.   The  byte
       array  must always have a null byte after the last data byte, at offset
       length; this allows string(3,n) representations to  be  treated  as  conven-
       tional  null-terminated C strings.  C programs use Tcl_GetStringFromObj
       and Tcl_GetString to get an object's string(3,n) representation.   If  bytes
       is NULL, the string(3,n) representation is invalid.

       An object's type manages its internal representation.  The member type-
       Ptr points to the Tcl_ObjType structure that describes  the  type.   If
       typePtr is NULL, the internal representation is invalid.

       The internalRep union member holds an object's internal representation.
       This is either a (long) integer, a double-precision floating point num-
       ber,  a  pointer to a value containing additional information needed by
       the object's type to represent the object, or two arbitrary pointers.

       The refCount 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.  Main-
       taining the correct reference count is a key responsibility  of  exten-
       sion  writers.   Reference  counting  is discussed below in(1,8) the section
       STORAGE MANAGEMENT OF OBJECTS.

       Although extension writers can directly access(2,5) 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(2,n,1 builtins)  or  update(7,n)
       refCount  directly; they should use macros such as Tcl_IncrRefCount and
       Tcl_IsShared instead.

       A key property of Tcl objects is that they  hold  two  representations.
       An object typically starts out containing only a string(3,n) representation:
       it is untyped and has a NULL typePtr.  An object  containing  an  empty
       string(3,n)  or  a copy of a specified string(3,n) is created using Tcl_NewObj or
       Tcl_NewStringObj respectively.  An object's string(3,n) value is gotten with
       Tcl_GetStringFromObj   or   Tcl_GetString  and  changed  with  Tcl_Set-
       StringObj.  If the object is later passed to a procedure like  Tcl_Get-
       IntFromObj that requires a specific internal representation, the proce-
       dure will create one and set(7,n,1 builtins) the object's typePtr.  The internal repre-
       sentation  is computed from the string(3,n) representation.  An object's two
       representations are duals of  each  other:  changes  made  to  one  are
       reflected in(1,8) the other.  For example, Tcl_ListObjReplace will modify an
       object's internal representation and the next call to Tcl_GetStringFro-
       mObj or Tcl_GetString will reflect that change.

       Representations  are recomputed lazily for efficiency.  A change to one
       representation made by a procedure such as  Tcl_ListObjReplace  is  not
       reflected  immediately in(1,8) the other representation.  Instead, the other
       representation is marked invalid so that it is only regenerated  if(3,n)  it
       is  needed  later.   Most C programmers never have to be concerned with
       how this is done and simply use procedures such  as  Tcl_GetBooleanFro-
       mObj  or Tcl_ListObjIndex.  Programmers that implement their own object
       types must check for invalid representations and  mark  representations
       invalid  when necessary.  The procedure Tcl_InvalidateStringRep is used
       to mark an object's string(3,n) representation invalid and to free any stor-
       age associated with the old string(3,n) representation.

       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(3,n) in(1,8) an object with repeated calls to
       Tcl_AppendToObj, and then call Tcl_ListObjIndex to extract a list  ele-
       ment  from  the  object.  The same object holding the same string(3,n) 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 Tcl_ConvertToType procedure.   Only  program-
       mers  that  create new object types need to be concerned about how this
       is done.  A procedure defined as part of the object type's  implementa-
       tion  creates  a  new internal representation for an object and changes
       its typePtr.  See the man(1,5,7) page for Tcl_RegisterObjType to  see  how  to
       create a new object type.


EXAMPLE OF THE LIFETIME OF AN OBJECT
       As  an  example  of  the  lifetime of an object, consider the following
       sequence of commands: set(7,n,1 builtins) x 123 This assigns to  x  an  untyped  object
       whose  bytes  member  points  to 123 and length member contains 3.  The
       object's typePtr member is NULL.  puts(3,n) "x is $x" x's string(3,n) representa-
       tion is valid (since bytes is non-NULL) and is fetched for the command.
       incr x The incr command first gets(3,n) an integer from x's object by  call-
       ing  Tcl_GetIntFromObj.   This  procedure  checks whether the object is
       already an integer object.  Since it is not, it converts the object  by
       setting  the  object's  internalRep.longValue member to the integer 123
       and setting the object's typePtr to point to  the  integer  Tcl_ObjType
       structure.   Both  representations  are now valid.  incr increments the
       object's integer internal representation then  invalidates  its  string(3,n)
       representation  (by  calling  Tcl_InvalidateStringRep) since the string(3,n)
       representation no longer corresponds to  the  internal  representation.
       puts(3,n)  "x  is  now $x" The string(3,n) representation of x's object is needed
       and is recomputed.  The string(3,n) representation is  now  124.   and  both
       representations are again valid.


STORAGE MANAGEMENT OF OBJECTS
       Tcl  objects are allocated on the heap and are shared as much as possi-
       ble 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 Tcl_NewObj or Tcl_NewStringObj  has  refCount
       0.   The  macro  Tcl_IncrRefCount increments the reference count when a
       new reference to the object is  created.   The  macro  Tcl_DecrRefCount
       decrements  the  count when a reference is no longer needed and, if(3,n) the
       object's reference count drops to zero, frees its storage.   An  object
       shared  by  different code or data structures has refCount greater than
       1.  Incrementing an object's reference count ensures that it  won't  be
       freed too early or have its value change accidently.

       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  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 refer-
       ence count.  When an object's reference count drops less(1,3) than or  equal
       to  zero,  Tcl_DecrRefCount  reclaims its storage.  Most command proce-
       dures 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(3,n) they do retain a pointer  to  an
       object  in(1,8) a data structure, they must be careful to increment its ref-
       erence count since the retained pointer is a new reference.

       Command procedures that directly modify objects such as those for  lap-
       pend  and linsert must be careful to copy a shared object before chang-
       ing it.  They must first check whether the object is shared by  calling
       Tcl_IsShared.   If  the  object  is shared they must copy the object by
       using Tcl_DuplicateObj; this returns a new duplicate  of  the  original
       object  that  has refCount 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(1,8)  the command procedure that
       implements linsert.  This procedure modifies the list object passed  to
       it in(1,8) objv[1] by inserting objc-3 new elements before index.  listPtr =
       objv[1];  if(3,n)  (Tcl_IsShared(listPtr))  {       listPtr  =  Tcl_Duplica-
       teObj(listPtr);  }  result = Tcl_ListObjReplace(interp, listPtr, index,
       0, (objc-3), &(objv[3])); As another example, incr's command  procedure
       must  check whether the variable's object is shared before incrementing
       the integer in(1,8) its internal representation.  If it is shared, it  needs
       to duplicate the object in(1,8) order to avoid accidently changing values in(1,8)
       other data structures.


SEE ALSO
       Tcl_ConvertToType,     Tcl_GetIntFromObj,     Tcl_ListObjAppendElement,
       Tcl_ListObjIndex, Tcl_ListObjReplace, Tcl_RegisterObjType


KEYWORDS
       internal  representation,  object, object creation, object type, refer-
       ence counting, string(3,n) representation, type conversion



Tcl                                   8.1                           Tcl_Obj(3)

References for this manual (incoming links)