627.md at [a421425dfd]

Login

File tip/627.md artifact 01881eccab part of check-in a421425dfd


# TIP 627: New functions for handling commands > 2^31 elements (for 8.7)
        Author:        Jan Nijtmans <[email protected]>
        State:         Final
        Type:          Project
        Vote:          Done
        Created:       01-06-2022
        Tcl-Version:   8.7
        Keywords:      Tcl
        Tcl-Branch:    tip-627
        Vote-Summary   Accepted 3/0/1
        Votes-For:     JN, KBK, KW
        Votes-Against: none
        Votes-Present: FV
-----

# Abstract

This TIP proposes 4 new functions:

 * `Tcl_CreateObjCommand2`
 * `Tcl_CreateObjTrace2`
 * `Tcl_NRCreateCommand2`
 * `Tcl_NRCallObjProc2`

Those functions do the same as `Tcl_CreateObjCommand`/`Tcl_CreateObjTrace`/`Tcl_NRCreateCommand`/`Tcl_NRCallObjProc`,
but their `Tcl_ObjCmdProc *` argument is now of type `Tcl_ObjCmdProc2 *`, and
`Tcl_CmdObjTraceProc *` (for `Tcl_CreateObjTrace2`) is now of type `Tcl_CmdObjTraceProc2 *`.
Those new types can handle more than 2^31 command line arguments when used in Tcl 9.0.

# Specification

The following new functions are defined:

 * `Tcl_CreateObjCommand2(Tcl_Interp *, const char *, Tcl_ObjCmdProc2 *, ClientData, Tcl_CmdDeleteProc *)`
 * `Tcl_CreateObjTrace2(Tcl_Interp *, Tcl_Size, int, Tcl_CmdObjTraceProc2 *, ClientData, Tcl_CmdObjTraceDeleteProc *)`
 * `Tcl_NRCreateCommand2(Tcl_Interp *, const char *, Tcl_ObjCmdProc2 *, Tcl_ObjCmdProc2 *, ClientData, Tcl_CmdDeleteProc *)`
 * `Tcl_NRCallObjProc2(Tcl_Interp *, Tcl_ObjCmdProc2 *, ClientData, Tcl_Size, Tcl_Obj *const *)`


The definitions of the new types are:
<pre>
typedef int (Tcl_ObjCmdProc2) (ClientData clientData, Tcl_Interp *interp,
	Tcl_Size objc, struct Tcl_Obj *const *objv);
typedef int (Tcl_CmdObjTraceProc2) (ClientData clientData, Tcl_Interp *interp,
	Tcl_Size level, const char *command, Tcl_Command commandInfo, Tcl_Size objc,
	Tcl_Obj *const *objv);
</pre>
Note that the `objc` argument changed type from `int` to `Tcl_Size`.

Those functions allow extensions to register commands or trace functions which can handle
more than 2^31 elements. Since the Tcl core cannot handle commands with more than
2^31 elements yet, this - for now - is of limited usability: The core should first be
extended to handle this everywhere, which is a massive amount of work. Therefore,
I am choosing to submit this part separately, so it can be used in Tcl 8.7 as well.
A later [TIP #626](626.md) (for Tcl 9.0), which makes the actual transition
making it really useful, can then decided upon separately. Also, if the API is
decided upon, the actual transition could even be delayed until Tcl 9.1: As
long as the API stays the same, it is considered an upwards compatible
change, no matter how it is handled internally.

Starting with Tcl 9.0, the `Tcl_CmdInfo` struct gets two additional
elements:
<pre>
typedef struct {
    ...
    Tcl_ObjCmdProc2 *objProc2;	/* Command's object2-based function. */
    void *objClientData2;	/* ClientData for object2 proc. */
} Tcl_CmdInfo;
</pre>
After calling the function `Tcl_GetCommandInfo()`, if `Tcl_CreateObjCommand2`
was used for registering the command, those fields will contain the
original function and clientData used in `Tcl_CreateObjCommand2`.
This change cannot be made in Tcl 8.7, since `Tcl_CmdInfo` is
usually allocated on the C-stack: Enlarging a struct size
(and writing the additional fields) is not considered binary
compatible. In Tcl 9.0, binary compatibility is lost anyway,
there we can afford this addition. Also - Tcl 9.0 only -,
when `Tcl_CreateObjCommand2` is used, the `isNativeObjectProc`
will be set to `2`. Current code is normally checking `isNativeObjectProc`
for being !=0, in order to see whether `objProc`/`objClientData`
is usable. That's still true: if `isNativeObjectProc` is `2`,
`objProc`/`objClientData` will contain wrapper information,
resulting in calling `objProc2`/`objClientData2`. So, no
current code needs to be adapted for Tcl 9.0: The promise
of source compatibility is still kept.

# Addendum

After [TIP #665](665.md) was accepted, a lot of functions changed from
using size\_t to Tcl\_Size parameters. In order to prevent confusion,
this change has been adapted in the TIP text above as well.

# Implementation

See branch [`tip-627`](https://core.tcl-lang.org/tcl/timeline?r=tip-627)

# Compatibility

The proposed change is 100% source and binary compatible with Tcl 8.6, since
the new functions are implemented as wrappers around the original functions.

# Copyright

This document has been placed in the public domain.