This section describes the internals of the InstVar../Tcl/Tcl.cc. This class defines the methods and mechanisms to bind a C++ member variable in the compiled shadow object to a specified OTcl instance variable in the equivalent interpreted object. The binding is set up such that the value of the variable can be set or accessed either from within the interpreter, or from within the compiled code at all times.
There are five instance variable classes: InstVarReal../Tcl/Tcl.cc, InstVarTime../Tcl/Tcl.cc, InstVarBandwidth../Tcl/Tcl.cc, InstVarInt../Tcl/Tcl.cc, and InstVarBool../Tcl/Tcl.cc, corresponding to bindings for real, time, bandwidth, integer, and boolean valued variables respectively.
We now describe the mechanism by which instance variables are set up. We use the InstVarReal../Tcl/Tcl.cc to illustrate the concept. However, this mechanism is applicable to all five types of instance variables.
When setting up an interpreted variable to access a member variable, the member functions of the class InstVar assume that they are executing in the appropriate method execution context; therefore, they do not query the interpreter to determine the context in which this variable must exist.
In order to guarantee the correct method execution context, a variable must only be bound if its class is already established within the interpreter, and the interpreter is currently operating on an object in that class. Note that the former requires that when a method in a given class is going to make its variables accessible via the interpreter, there must be an associated class TclClassSectionsec:TclClass defined that identifies the appropriate class hierarchy to the interpreter. The appropriate method execution context can therefore be created in one of two ways.
An implicit solution occurs whenever a new TclObject is created within the interpreter. This sets up the method execution context within the interpreter. When the compiled shadow object of the interpreted TclObject is created, the constructor for that compiled object can bind its member variables of that object to interpreted instance variables in the context of the newly created interpreted object.
An explicit solution is to define a bind-variables operation within a command function, that can then be invoked via the cmd method. The correct method execution context is established in order to execute the cmd method. Likewise, the compiled code is now operating on the appropriate shadow object, and can therefore safely bind the required member variables.
An instance variable is created by specifying the name of the interpreted variable, and the address of the member variable in the compiled object. The constructor../Tcl/Tcl.ccInstVar::InstVar for the base class InstVar creates an instance of the variable in the interpreter, and then sets up a trap routine../Tcl/Tcl.ccInstVar::catch_var to catch all accesses to the variable through the interpreter.
Whenever the variable is read through the interpreter, the trap routine../Tcl/Tcl.ccInstVar::catch_read is invoked just prior to the occurrence of the read. The routine invokes the appropriate get function../Tcl/Tcl.ccInstVarReal::get that returns the current value of the variable. This value is then used to set the value of the interpreted variable that is then read by the interpreter.
Likewise, whenever the variable is set through the interpreter, the trap routine../Tcl/Tcl.ccInstVar::catch_write is invoked just after to the write is completed. The routine gets the current value set by the interpreter, and invokes the appropriate set function../Tcl/Tcl.ccInstVarReal::set that sets the value of the compiled member to the current value set within the interpreter.
Tom Henderson 2011-11-05