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_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
       Tcl_Obj *objPtr (in)	     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 ar-
       ray  of pointers	to the objects for each	list element.  Dual-ported ob-
       jects 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  instruc-
       tion 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.  Be-
       cause of	this representation invalidation and regeneration, it is  dan-
       gerous  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  re-
       claim 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  in-
       cluding integer,	double,	list, and bytecode.  Extension writers can ex-
       tend 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 al-
       ways have a null	byte after the last data byte, at offset length;  this
       allows string representations to	be treated as conventional null-termi-
       nated C strings.	 C programs use	Tcl_GetStringFromObj and Tcl_GetString
       to get an object's string representation.  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 re-
       fCount 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 re-
       flected 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  se-
       quence 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 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 object by calling
       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  set-
       ting  the  object's  typePtr to point to	the integer Tcl_ObjType	struc-
       ture.  Both representations are now valid.   incr  increments  the  ob-
       ject's integer internal representation then invalidates its string rep-
       resentation (by calling Tcl_InvalidateStringRep)	since the string  rep-
       resentation 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 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  de-
       termine 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	decre-
       ments  the  count  when a reference is no longer	needed and, if the ob-
       ject'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 us-
       ing Tcl_DuplicateObj; this returns a new	duplicate of the original  ob-
       ject  that  has	refCount  0.  If the object is not shared, the command
       procedure "owns"	the object and can safely modify it directly.  For ex-
       ample,  the following code appears in the command procedure that	imple-
       ments 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_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 its  in-
       ternal  representation.	If it is shared, it needs to duplicate the ob-
       ject 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)

NAME | SYNOPSIS | ARGUMENTS | INTRODUCTION | THE TCL_OBJ STRUCTURE | EXAMPLE OF THE LIFETIME OF AN OBJECT | STORAGE MANAGEMENT OF OBJECTS | SEE ALSO | KEYWORDS

Want to link to this manual page? Use this URL:
<https://www.freebsd.org/cgi/man.cgi?query=Tcl_DecrRefCount.tcl85&sektion=3&manpath=FreeBSD+13.0-RELEASE+and+Ports>

home | help