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_BounceRefCount, Tcl_IsShared, Tcl_InvalidateStringRep -  manipulate
       Tcl values

SYNOPSIS
       #include	<tcl.h>

       Tcl_Obj *
       Tcl_NewObj()

       Tcl_Obj *
       Tcl_DuplicateObj(objPtr)

       Tcl_IncrRefCount(objPtr)

       Tcl_DecrRefCount(objPtr)

       Tcl_BounceRefCount(objPtr)

       int
       Tcl_IsShared(objPtr)

       Tcl_InvalidateStringRep(objPtr)3

ARGUMENTS
       Tcl_Obj *objPtr (in)	     Points to a value;	must have been the re-
				     sult of a previous	call to	Tcl_NewObj.
______________________________________________________________________________

INTRODUCTION
       This  man  page presents	an overview of Tcl values (called Tcl_Objs for
       historical reasons) and how they	are used.  It also  describes  generic
       procedures  for managing	Tcl values.  These procedures are used to cre-
       ate and copy values, and	increment and decrement	the  count  of	refer-
       ences  (pointers)  to  values.	The procedures are used	in conjunction
       with ones that operate on specific types	of values such as  Tcl_GetInt-
       FromObj	and  Tcl_ListObjAppendElement.	 The individual	procedures are
       described along with the	data structures	they manipulate.

       Tcl's dual-ported values	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  values  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
       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	 representation	is immediately
       available.  The compiler	itself uses Tcl	values 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 values contain an	internal representation, their
       semantics are defined in	terms of strings: an up-to-date	string can al-
       ways be obtained, and any change	to the value will be reflected in that
       string  when  the value'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_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
       significantly  reduces storage requirements because some	values 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 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_Size refCount;
		  char *bytes;
		  Tcl_Size 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;
		      struct {
			  void *ptr;
			  Tcl_Size size;
		      }	ptrAndSize;
		  } internalRep;
	      }	Tcl_Obj;

       The bytes and the length	members	together hold a	value'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 a	value's	string representation.	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 type-
       Ptr 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 num-
       ber,  a	pointer	to a value containing additional information needed by
       the value's type	to represent the value,	a Tcl_WideInt integer, two ar-
       bitrary pointers, a pair	made up	of a pointer and an unsigned long  in-
       teger,  or  a  pair made	up of a	pointer	and Tcl_Size which is a	signed
       integer type capable of holding the maximum lengths permitted in	Tcl.

       The refCount member is used to tell when	it is safe to free  a  value's
       storage.	  It holds the count of	active references to the value.	 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 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 re-
       fCount  directly;  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_New-
       StringObj respectively.	A value's string value is gotten with Tcl_Get-
       StringFromObj  or  Tcl_GetString	and changed with Tcl_SetStringObj.  If
       the value is later passed to a procedure	 like  Tcl_GetIntFromObj  that
       requires	 a specific internal representation, the procedure will	create
       one and set the value's typePtr.	 The internal representation  is  com-
       puted  from  the	 string	representation.	 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_GetStringFromObj  or  Tcl_Get-
       String 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 value
       types must check	for invalid representations and	 mark  representations
       invalid	when necessary.	 The procedure Tcl_InvalidateStringRep is used
       to mark a value's string	representation invalid and to free any storage
       associated with the old string representation.

       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 ele-
       ment from the value.  The same value holding the	same string value  can
       have  several  different	 internal  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  concerned  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 type-
       Ptr.  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 se-
       quence 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_GetIntFromObj.  This	procedure checks whether the value is  already
       an  integer  value.   Since it is not, it converts the value by setting
       the value's internal 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 in-
       ternal 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	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	deter-
       mine when a value is no longer needed and can safely be freed.  A value
       just created by Tcl_NewObj, Tcl_NewStringObj, or	any Abstract List com-
       mand or function, has refCount 0, meaning that the object can often  be
       given to	a function like	Tcl_SetObjResult, Tcl_ListObjAppendElement, or
       Tcl_DictObjPut  (as a value) without explicit reference management, all
       of which	are common use cases. (The latter two require that the	target
       list  or	 dictionary  be	well-formed, but that is often easy to arrange
       when the	value is being initially constructed.)	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. If the value's reference count drops  to
       zero,  frees  its  storage.  The	macro Tcl_BounceRefCount will check if
       the value has no	references (i.e. in a "new" state) and free the	value.
       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
       assigns	the call's argument values 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 a value's reference count drops less than or equal to
       zero, Tcl_DecrRefCount reclaims its storage.

       Most command procedures have not	been concerned about reference	count-
       ing  since  they	use a value immediately	and do not retain a pointer to
       the value after they return.  However, there are	some  procedures  that
       may  return a new value,	with a refCount	of 0. In this situation, it is
       the caller's responsibility to free the value before the	procedure  re-
       turns.  One way to cover	this is	to always call Tcl_IncrRefCount	before
       using the value,	then call Tcl_DecrRefCount before returning. The other
       way is to use Tcl_BounceRefCount	after the value	is no longer needed or
       referenced. This	macro will free	the value if there are no other	refer-
       ences  to  the  value.  When  retaining	a pointer to a value in	a data
       structure the procedure must be	careful	 to  increment	its  reference
       count since the retained	pointer	is a new reference. Examples of	proce-
       dures that return new values are	Tcl_NewIntObj, and commands like lseq,
       which creates an	Abstract List, and an lindex on	this list may return a
       new Obj with a refCount of 0.

       Command	procedures  that directly modify values	such as	those for lap-
       pend 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 lin-
       sert.  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
       variable's value	is shared before incrementing the integer in  its  in-
       ternal  representation.	 If  it	 is  shared, it	needs to duplicate the
       value in	order to avoid accidentally  changing  values  in  other  data
       structures.

       In  cases  where	a value	is obtained, used, and not retained, the value
       can be freed using Tcl_BounceRefCount. This is functionally  equivalent
       to calling Tcl_IncrRefCount followed Tcl_DecrRefCount.

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,  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_InvalidateStringRep.tcl90&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help