TIP 445: Tcl_ObjType Utility Routines

Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2017 Conference, Houston/TX, US, Oct 16-20
Send your abstracts to tclconference@googlegroups.com
by Aug 21.
Author:         Don Porter <dgp@users.sourceforge.net>
State:          Draft
Type:           Project
Vote:           Pending
Created:        18-Mar-2016
Post-History:   
Tcl-Version:	8.7

Abstract

Proposes additional public routines useful for extensions that implement custom **Tcl_ObjType_s.

Background

When an extension creates a custom Tcl_ObjType it needs to operate on the fields of the Tcl_Obj and the Tcl_ObjType structs.

Almost all of these operations have been nicely encapsulated in utility routines, so for example, an extension calls Tcl_GetString to make sure a value is set for objPtr->bytes, rather than worrying about the backing details of calling the routine objPtr->typePtr->updateStringProc (if present) for itself. Likewise Tcl_DuplicateObj routes processing to type-specific routines as needed.

There are gaps in this interface. Most glaring is the lack of any way to call the freeIntRepProc of an incumbent type other than directly through the typePtr field. Another missing bit is an encapsulated way to set the string rep without direct manipulation of the bytes and length fields. Within Tcl itself, there are internal utility macros TclFreeIntRep and TclInitStringRep for these tasks, but extensions have nothing.

Besides convenience, utility routines such as these improve chances for correctness, since they bring constraints into one place instead of many places. For example, the requirement that when objPtr->typePtr is not NULL, it must be paired with an appropriate objPtr->internalRep. The TclFreeIntRep macro has a history of fixing such bugs. A corresponding routine will offer the same benefit to extensions.

Proposal

Add to Tcl's stub table of public C routines a new routine

void Tcl_FreeIntRep(Tcl_Obj* objPtr)

that performs precisely the same task as the existing internal macro TclFreeIntRep.

Add to Tcl's stub table of public C routines a new routine

char * Tcl_InitStringRep(Tcl_Obj* objPtr, const char* bytes, unsigned int numBytes)

that performs the function of the existing internal macro TclInitStringRep, but is extended to return a pointer to the string rep, and to accept NULL as a value for bytes. When bytes is NULL and objPtr has no string rep, an uninitialzed buffer of numBytes bytes is created for filling by the caller. When bytes is NULL and objPtr has a string rep, the string rep will be truncated to a length of numBytes bytes. When numBytes is greater than zero, and the returned pointer is NULL, that indicates a failure to allocate memory for the string representation. The caller may then choose whether to raise an error or panic.

Add to Tcl's stub table of public C routines a new routine

int Tcl_HasStringRep(Tcl_Obj* objPtr)

that returns a boolean indicating whether or not a string rep is currently stored in objPtr. This is used when the caller wants to act on objPtr differently depending on whether or not it is a pure value. Typically this only makes sense in an extension if it is already known that objPtr possesses an internal type that is managed by the extension.

Define a new public type

typedef union Tcl_ObjIntRep {...} Tcl_ObjIntRep

where the contents are exactly the existing contents of the union in the internalRep field of the Tcl_Obj struct. This definition permits us to pass internal representations and pointers to them as arguments and results in public routines.

Add to Tcl's stub table of public C routines a new routine

void Tcl_StoreIntRep(Tcl_Obj* objPtr, const Tcl_ObjType* typePtr, const Tcl_ObjIntRep* irPtr)

which stores in objPtr a copy of the internal representation pointed to by irPtr and sets its type to typePtr. When irPtr is NULL, this leaves objPtr without a representation for type typePtr.

Add to Tcl's stub table of public C routines a new routine

Tcl_ObjIntRep* Tcl_FetchIntRep(Tcl_Obj* objPtr, const Tcl_ObjType* typePtr)

which returns a pointer to the internal representation stored in objPtr that matches the requested type typePtr. If no such internal representation is in objPtr, return NULL.

Compatibility

These are new routines, so they have no compatibility concerns in the sense of cause trouble for existing working code.

They do help set up an improved compatibility scenario for the future however. Extensions that use these new routines to stop directly referring to the fields of the Tcl_Obj and Tcl_ObjType structs are prepared to support a source-compatible migration to a Tcl 9 that might then be free to make revisions to those structs.

Implementation

Taking shape on the tip-445 branch.

Rejected Alternatives

Copyright

This document has been placed in the public domain.

History