back to index

Object references (Pointers)

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).

Typed pointers

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();

Untyped pointers

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


Deleting an object

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
    

Pointer arguments

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");

Memory management

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).


back to index

TkScript and the TkScript documentation are (c) Copyright 2001-2004 by Bastian Spiegel.