Architectural Limits of Variables
Variables are currently intended to be used in the object
instantiation process, and while the current mechanisms could be
extended toward a run time use, but many problems have to be solved;
the main problem is that currently the referential integrity of the
system are guaranted by the following:
- Variable values have the same lifetime of objects
- Variable values are only referred thru variable names
- Variable values are private data to an object using them, and are
not communicated to the external world with any means different than the
variable binding.
These constraint assure that when an object is destroyed, the variable
value is destroied, and all the object using this value are recomputed,
and no pending reference to the destroyed value are left anywhere.
Supporting a run time use of variable values imply substituting this
mechanisms with equivalent run-time mechanisms; note that in general
garbage collection is not always sufficent, because a garbage collected
based system do not work very well with object that have an explicit,
intentional, close/destroy operation.
Immagine for example a device
object that define a
variable bound to an open device; destroying the device object imply,
at least, closing the device; suppose that there are references to
this device created passing a reference to this device at run time;
the standard garbage collector technique would be to wait that this
device is de-referenced before closing it; this is of course not
possible (think of a sound file device where at the end you find an
undetermined amount of silence added waiting for the garbage collector
to close the file); all the references to this object must have a way
to know when the object is closed/destroyed.
Garbage collectors techniques work well when the semantic of a value
is not tied to its existence, but its use.
Solutions for this kind of problems exists, but their complexity is surely
quite bigger than the current set of solutions and algorithm.
Note: the system currently have a bug in the referential integrity: the
metaclass discrimination data base can store a permanent pointer to
a value obtained thru a variable argument; in general, this pointer is not
dereferenced, but it could with a special purpose equivalence function;
this problem need a good solution.
An other limit in the current algorithm is that the almost everywhere
in the code there is the assumption that a scope is closed by a patcher;
inserting an explicit scope operator, like '::' in C++, like for
example composed names ($foo.bar), will break this assumption, and many critical
parts of the algorithm will not work any more, in particular the object
stealing; the whole code base should be carefully reviewed before
a scope operator can be added.
Main Data Structures
The basic types for the variable handling are defined in the file mess_types.h
.
fts_binding_t
: it is the implementation of the binding of a name to a value.
i.e. the low level implementation of a variable; for each variable name and scope there
can be at most one binding structure.
A binding structure include the name of the variable, a flag to tell if the
binding is suspended or not, the value of the variable, a list of the objects
using the variable and a list of object defining a variable (to handle double
definition errors).
-
fts_env_t
: it is a list of bindings; represent the set of
bindings existing inside a given scope; it is just a list of fts_binding_t
.
- in the
fts_object_t
: each object store the name of the variable
the object define (if any) and the list of bindings the object refer.
- in the
fts_patcher_t
: each patcher store an instance of fts_env_t
that represent the definitions existing in the patcher.
Main Functions
The variables.c
define three groups of functions,
one for bindings (static functions named fts_binding_*
),
one for env (static functions named fts_env_*
),
and a public set of functions for variables themselves, named
fts_variable_*
.
Binding related functions
- fts_binding_new
- fts_binding_delete
- Create and delete new Bindings
- fts_binding_suspend
- fts_binding_restore
- fts_binding_is_suspended
- Handle variable suspension and restoring at the binding level.
- fts_binding_add_user
- fts_binding_remove_user
- Handle the binding user list, i.e. the list of objects referring this variable.
- fts_binding_add_definition
- fts_binding_remove_definition
- fts_binding_defined_by
- fts_binding_defined_only_by
- Handle the binding definition list, i.e. the list of objects defining this binding;
if there are more than one objects defining the same object, we are in an error situation
(double definition).
Environment related functions
- fts_env_init
- Initialize a patcher environment.
- fts_env_add_binding
- fts_env_remove_bindings
- Add and remove bindings from an environment.
- fts_env_remove_suspended_bindings
- Remove all the bindings belonging to a specif owner, that are currently
suspended; used by the patcher to suppress old variables after a redefinition.
- fts_env_suspend_bindings
- suspend all the bindings in the environment belonging to an owner.
Used by the patcher during patcher redefinition.
- fts_env_get_binding
- Find a binding for a variable, in the current binding.
Variable related, public functions
These functions are commented with more details in the
variables.h
file; the variable is specified with a
name/scope pair, not with internal structures, and in general they
look for the correct binding following the scoping rules.
- fts_variable_define
- fts_variable_can_define
- fts_variable_undefine
- fts_variables_undefine
- fts_variables_undefine_suspended
- Define and undefine variables in a given scope, as their
bindings correspondent.
- fts_variable_is_suspended
- fts_variable_suspend
- fts_variables_suspend
- fts_variable_restore
- Handle suspending and restoring of variables.
- fts_variable_get_value
- Access a variable value.
- fts_variable_add_user
- Add a user to a variable, i.e. an object referring it.
Related Files
The variable propagation algorithm is implemented parly in variables
specific files, but is also supported by specific code in object
instantiation and redefinition; so check also some of the
object and
expressions
related files.