4.10. Foreign Objects¶
clonable
proxy
fctProxy
foreignFct
foreignCode
The low level aspects of interfacing with code written in other languages (via C or C++ glue code)
are described in Virtual Machine Reference (chapter 8). A number of objects in the Self
world are used to interface to foreign data objects and functions. These objects are found in the name spaces
traits foreign, and globals foreign.
One difficulty in interfacing between Self and external data and functions is that references to foreign
data and functions from within Self can become obsolete when the Self world is saved as
a snapshot and then read in later, possibly on some other workstation. Using an obsolete reference
(i.e., memory address) would be disastrous. Thus, Self encapsulates such references within the
special objects proxy (for data references) and fctProxy (for function references). Such objects
are known collectively as proxies. A proxy object bundles some extra information along with the
memory address of the referenced object and uses this extra information to detect (with high probability)
any attempt to use an obsolete proxy. An obsolete proxy is called a dead proxy.
To make it possible to rapidly develop foreign code, the virtual machine supports dynamic linking
of this code. This makes it unnecessary to rebuild the virtual machine each time a small change is
made to the foreign code. Dynamic linking facilities vary from platform to platform, but the Self
interface to the linking facilities is largely system independent. The SunOS/Solaris dynamic link
interface is defined in the sunLinker object. However, clients should always refer to the dynamic
linking facilities by the name linker, which will be initialized to point to the dynamic linker interface
appropriate for the current platform.
The linker, proxy and fctProxy objects are rather low level and have only limited functionality.
For example, a fctProxy does not know which code file it is dependent on. The objects
foreignFct and foreignCode establish a higher level and easier to use interface. A foreign-Code
object represents an “object file” (a file with executable code). It defines methods for loading
and unloading the object file it represents. A foreignFct object represents a foreign routine. It
understands messages for calling the foreign routine and has associated with it a foreignCode
object. The foreignFct and foreignCode objects cooperate with the linker, to ensure that
object files are transparently loaded when necessary and that fctProxies depending on an object
file are killed when the object file is unloaded, etc.
The foreignCodeDB object ensures that foreignCode objects are unique, given a path. It also
allows for specifying initializers and finalizers on foreignCode objects. An initializer is a foreign
routine that is called whenever the object file is loaded. Initializers take no arguments and do not
return values. Typically, they initialize global data structures. Finalizers are called when an object
file is unloaded. When debugging foreign routines, foreignCodeDB printStatus outputs a
useful overview.
Normal use of a foreign routine simply involves cloning a foreignFct object to represent the foreign
routine. When cloning it, the name of the function and the path of the object file is specified.
It is then not necessary to worry about proxy, fctProxy and linker objects, etc. In fact, it is
recommended not to send messages directly to these objects, since this may break the higher level
invariants that foreignFct objects rely on.
Relevant oddballs:
linker Dynamic linker for current platform. sunLinker Dynamic linker implementation for SunOS/Solaris. foreignCodeDB Registry for foreignCode objects.
Modules: foreign