Tcl_IsShared man page on OpenMandriva

Man page or keyword search:  
man Server   8135 pages
apropos Keyword Search (all sections)
Output format
OpenMandriva logo
[printable version]

Tcl_Obj(3)		    Tcl Library Procedures		    Tcl_Obj(3)

______________________________________________________________________________

NAME
       Tcl_NewObj,   Tcl_DuplicateObj,	 Tcl_IncrRefCount,   Tcl_DecrRefCount,
       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)

       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
       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
       always 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_GetStringFro‐
       mObj 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
       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
       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_Get‐
       String  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
       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
       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
       refCount 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
       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_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 internalRep.longValue member 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	 inte‐
       ger  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 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 or Tcl_NewStringObj  has  refCount  0.   The
       macro Tcl_IncrRefCount increments the reference count when a new refer‐
       ence to the value is created.  The  macro  Tcl_DecrRefCount  decrements
       the count when a reference is no longer needed and, if the value's ref‐
       erence count drops to zero, frees its storage.  A value shared by  dif‐
       ferent code or data structures has refCount greater than 1.  Increment‐
       ing 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
       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 reference.

       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
       internal	 representation.   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_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)
[top]

List of man pages available for OpenMandriva

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net