manpagez: man pages & more
man Object(3)
Home | html | info | man
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  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 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 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 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  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 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 Tcl_Obj fields directly.  It
       is better to access 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  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.  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 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;
                       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 an object's  UTF-8  string  representation,  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 after the
       last data byte, at offset length; this allows string representations to
       be treated as conventional null-terminated C strings.  C  programs  use
       Tcl_GetStringFromObj and Tcl_GetString to get an object's string repre-
       sentation.  If bytes is NULL, the string 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, 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 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  the  section
       STORAGE MANAGEMENT OF OBJECTS.

       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 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 representation:
       it  is  untyped  and has a NULL typePtr.  An object containing an empty
       string or a copy of a specified string is created using  Tcl_NewObj  or
       Tcl_NewStringObj respectively.  An object's string 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 the object's typePtr.  The internal repre-
       sentation 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, 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 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_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 representation invalid and to free any stor-
       age associated with the old string 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 in 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  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 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  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 "x is $x" x's string representa-
       tion 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 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
       representation (by calling Tcl_InvalidateStringRep)  since  the  string
       representation  no  longer  corresponds to the internal representation.
       puts "x is now $x" The string representation of x's  object  is  needed
       and  is recomputed.  The string representation is now 124 and both rep-
       resentations 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  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 will not
       be freed too early or have its value change accidentally.

       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 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 do not 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  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  the  object and can safely modify it directly.  For example,
       the following code appears in the  command  procedure  that  implements
       linsert.   This  procedure  modifies  the  list  object 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_ListObjRe-
       place(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  its
       internal  representation.   If  it is shared, it needs to duplicate the
       object in order to avoid accidentally changing  values  in  other  data
       structures.


SEE ALSO

       Tcl_ConvertToType(3),    Tcl_GetIntFromObj(3),    Tcl_ListObjAppendEle-
       ment(3), Tcl_ListObjIndex(3),  Tcl_ListObjReplace(3),  Tcl_RegisterObj-
       Type(3)


KEYWORDS

       internal  representation,  object, object creation, object type, refer-
       ence counting, string representation, type conversion



Tcl                                   8.5                           Tcl_Obj(3)

Object 8.5.4 - Generated Tue Aug 19 20:56:10 CDT 2008
© manpagez.com 2000-2026
Individual documents may contain additional copyright information.