Object references are used to avoid time and memory costly copies of objects, for instance when object parameters are passed to functions or methods.
Multiple object variables may point to one and the same object but the TKS runtime takes care of memory management; i.e. only one pointer at a time may be the owner of an object and thus have the right to actually remove the object from memory.
The special variable type Pointer represents an untyped object pointer (which technically points to a YAC_Object C++ object)
Pointers/object references do not include type information about the object they point to; this information is rather obtained from the object itself given that it is allocated and not null.
An assignment of a type incompatible object datatype to a typed object variable will cause the script-engine to abort resp. raise an error when the variable is used in a statement or expression that needs to access the object (e.g. a method call or member access).
Example:
// Pointer assignment, t2 und t will point to the same memory area
// after this assignment. t will be the owner, t2 is deleted before
// the assignment
Time t, t2 <= t;
t2.now();
Example:
// Pointer assignment, unbound pointer returned by "new" expression
// is bound to an (untyped) variable which previous content is
// deleted before the assignment
Time t <= new Time;
t.now();
The virtual datatype Pointer is used to store references to arbitrary objects
Example:
// unbound pointer returned by "new" expression is bound to an // untyped variable
Pointer p <= new Time;
// this pointer is now dereferenced and bound to variable t
Time t<=deref p; t.now();
// the variable t becomes the owner of the object after the pointer // assignment (<=). Since 'p' is already unbound, the following
// statement does not affect 't':
p<=null;
Example:
String s="hello, world.";
Pointer p <= s; // Assignment to untyped object variable
String t <= p; // Assignment to typed object variable
trace "t="+t; // Debug-output of string content
trace "p="+p; // Debug-output of memory address and type
An object reference is deleted by assigning 0 (null) :
Example:
String s="hello, world.";
// delete object reference; the object will be removed from memory
// since 's' is the object's owner
s<=null;
trace "s="+s; // the pointer is <void> (0) now
Objects (and Strings) are always passed by reference (call-by-reference) while the scalars int und float are passed as a copy (call-by-value).
Arguments to C/C++ calls are always passed by reference, i.e. the memory management information (deleteme flag) is lost. If you need to pass read-write objects, variable argument types and/or argument lists please use Value and ListNode objects which can be created on-the-fly by using the #() and {} expressions.
Example:
function MyFunction(String _s) {
// directly modifies the parameter value
_s.append(", world.");
return _s;
}
trace MyFunction("Hello");
TkScript does not use a garbage collector but rather utilizes a simple (but effective and fast!) "read/write" pointer tracking system.
In fact, this allows API programmers to write their own (specialized) garbage collectors so the script "users" do not have to take care of that (example: tkfox plugin).
Each object reference stores a flag which hints the script engine whether it is safe to delete an object.
The deref expressions is used to unlink read/write objects from variables and make them volatile, so they can be bound to a new container.
The <= pointer assign statement only unlinks volatile objects and otherwise create a read-only reference to the given object.
the tcobject() and tcstring() expressions can be used to create copies of read-only objects so it becomes safe to store than in a container (e.g. variable, array, hashtable..).
the #() value expression can be used to wrap volatile objects in an object "hull".
the {} list expression can be used to wrap a list of volatile objects in object "hulls".
In contrary to other script engines TKScript allows you to mess up pointers by keeping references to already deleted objects. The runtime will raise an error if an "illegal" pointer is detected (but there are chances that this will cause a seg-fault).
Nevertheless, IMHO a programmer should be now what she/he is doing otherwise there are dozens of ways to shoot yourself in the foot. TkScript was designed for speed, the interpreted "debug" mode may help to discover faulty pointers but the JIT will simply numbercrunch your code so be careful not to keep references to temporary objects!
Each object has a "validation_tag" field which will read "YAC_VALID_TAG" as long as the object is "alive" but there are of course chances that the memory region has already been replaced by a new object. However, in practice this mechanism works quite well and should point you to some not-so-obvious mistakes (like e.g. keeping a string object that was returned by a stringlist iterator).