Manual Pages for UNIX Darwin command on man Tcl_InvalidateStringRep
MyWebUniversity

Manual Pages for UNIX Darwin command on man Tcl_InvalidateStringRep

TclObj(3) Tcl Library Procedures TclObj(3)

NAME

TclNewObj, TclDuplicateObj, TclIncrRefCount, TclDecrRefCount,

TclIsShared, TclInvalidateStringRep - manipulate Tcl objects

SYNOPSIS

##iinncclluuddee <>

TclObj * TTccllNNeewwOObbjj() TclObj * TTccllDDuupplliiccaatteeOObbjj(objPtr) TTccllIInnccrrRReeffCCoouunntt(objPtr) TTccllDDeeccrrRReeffCCoouunntt(objPtr) int TTccllIIssSShhaarreedd(objPtr) TTccllIInnvvaalliiddaatteeSSttrriinnggRReepp(objPtr) AARRGGUUMMEENNTTSS TclObj *objPtr (in) Points to an object; must have been the result of a previous call to TTccllNNeewwOObbjj. IINNTTRROODDUUCCTTIIOONN 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 TTccllGGeettIInnttFFrroommOObbjj and TTccllLLiissttOObbjjAAppppeennddEElleemmeenntt. 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 TTccllOObbjj fields directly. It

is better to access TclObj information using procedures like TTccllGGeett-

SSttrriinnggFFrroommOObbjj and TTccllGGeettSSttrriinngg. Objects are allocated on the heap and are referenced using a pointer to their TTccllOObbjj 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. Seven types are predefined in the Tcl core including integer, double, list, and bytecode. Extension writers can extend the set of types by using the procedure TTccllRReeggiisstteerrOObbjjTTyyppee . TTHHEE TTCCLLOOBBJJ SSTTRRUUCCTTUURREE Each Tcl object is represented by a TTccllOObbjj structure which is defined as follows. typedef struct TclObj { int refCount; char *bytes; int length; TclObjType *typePtr; union { long longValue; double doubleValue; VOID *otherValuePtr; struct { VOID *ptr1; VOID *ptr2; } twoPtrValue; } internalRep; } TclObj;

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 TTccllGGeettSSttrriinnggFFrroommOObbjj and TTccllGGeett-

SSttrriinngg 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 TclObjType 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 the section SSTTOORRAAGGEE MMAANNAAGGEEMMEENNTT OOFF OOBBJJEECCTTSS. Although extension writers can directly access the members of a TclObj 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 TTccllIInnccrrRReeffCCoouunntt and TTccllIIssSShhaarreedd 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 TTccllNNeewwOObbjj or TTccllNNeewwSSttrriinnggOObbjj respectively. An object's string value is gotten with

TTccllGGeettSSttrriinnggFFrroommOObbjj or TTccllGGeettSSttrriinngg and changed with TTccllSSeett-

SSttrriinnggOObbjj. If the object is later passed to a procedure like TTccllGGeett-

IInnttFFrroommOObbjj 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, TTccllLLiissttOObbjjRReeppllaaccee will modify an

object's internal representation and the next call to TTccllGGeettSSttrriinnggFFrroo-

mmOObbjj or TTccllGGeettSSttrriinngg will reflect that change. Representations are recomputed lazily for efficiency. A change to one representation made by a procedure such as TTccllLLiissttOObbjjRReeppllaaccee 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 TTccllGGeettBBoooolleeaannFFrroo-

mmOObbjj or TTccllLLiissttOObbjjIInnddeexx. Programmers that implement their own object types must check for invalid representations and mark representations invalid when necessary. The procedure TTccllIInnvvaalliiddaatteeSSttrriinnggRReepp 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

TTccllAAppppeennddTTooOObbjj, and then call TTccllLLiissttOObbjjIInnddeexx 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 TTccllCCoonnvveerrttTTooTTyyppee 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 TTccllRReeggiisstteerrOObbjjTTyyppee to see how to create a new object type. EEXXAAMMPPLLEE OOFF TTHHEE LLIIFFEETTIIMMEE OOFF AANN OOBBJJEECCTT As an example of the lifetime of an object, consider the following sequence of commands: sseett xx 112233 This assigns to x an untyped object whose bytes member points to 112233 and length member contains 3. The object's typePtr member is NULL.

ppuuttss ""xx iiss $$xx""

x's string representation is valid (since bytes is non-NULL) and is

fetched for the command. iinnccrr xx The iinnccrr command first gets an integer from x's object by calling TTccllGGeettIInnttFFrroommOObbjj. 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 112233 and set-

ting the object's typePtr to point to the integer TclObjType struc-

ture. Both representations are now valid. iinnccrr increments the object's integer internal representation then invalidates its string representation (by calling TTccllIInnvvaalliiddaatteeSSttrriinnggRReepp) since the string representation no longer corresponds to the internal representation.

ppuuttss ""xx iiss nnooww $$xx""

The string representation of x's object is needed and is recomputed. The string representation is now 112244. and both representations are again valid. SSTTOORRAAGGEE MMAANNAAGGEEMMEENNTT OOFF OOBBJJEECCTTSS

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 TTccllNNeewwOObbjj or TTccllNNeewwSSttrriinnggOObbjj has refCount 0. The macro TTccllIInnccrrRReeffCCoouunntt increments the reference count when a new reference to the object is created. The macro TTccllDDeeccrrRReeffCCoouunntt 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 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 TTccllIInnccrrRReeffCCoouunntt 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 TTccllDDeeccrrRReeffCCoouunntt to decrement each argument's refer-

ence count. When an object's reference count drops less than or equal

to zero, TTccllDDeeccrrRReeffCCoouunntt 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 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 llaapp-

ppeenndd and lliinnsseerrtt must be careful to copy a shared object before chang-

ing it. They must first check whether the object is shared by calling TTccllIIssSShhaarreedd. If the object is shared they must copy the object by using TTccllDDuupplliiccaatteeOObbjj; 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 the command procedure that implements lliinnsseerrtt. This procedure modifies the list object passed to

it in objv[1] by inserting objc-3 new elements before index.

listPtr = objv[1]; if (TclIsShared(listPtr)) { listPtr = TclDuplicateObj(listPtr); }

result = TclListObjReplace(interp, listPtr, index, 0, (objc-3), &(objv[3]));

As another example, iinnccrr'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 accidently changing values in other data structures.

SEE ALSO

TclConvertToType, TclGetIntFromObj, TclListObjAppendElement, TclListObjIndex, TclListObjReplace, TclRegisterObjType KKEEYYWWOORRDDSS

internal representation, object, object creation, object type, refer-

ence counting, string representation, type conversion Tcl 8.1 TclObj(3)




Contact us      |      About us      |      Term of use      |       Copyright © 2000-2019 MyWebUniversity.com ™