References
The Intermediate Language provides mechanisms for linking different pieces of code together, and
even to dynamically modify the linking at runtime. These mechanisms are based around the types
core.asm.Reference
, core.asm.RefSource
, and core.asm.Content
.
Content
The type core.asm.Content
represents something in memory that it should be possible to
refer to. For example, code generated by the Intermediate Language is stored in a
core.asm.Binary
object, which inherits from core.asm.Content
. It is possible
to create arbitrary subclasses of Content
to refer to arbitrary things in the system.
RefSource
The type core.asm.RefSource
represents something that has an identity, to which one may
refer. The RefSource
has at most one Content
that provides the actual target for the reference.
It is possible to replace the Content
of the RefSource
at any point. This action updates any
references that refer to the RefSource
.
Due to this design, it is useful to think of the RefSource
itself as the name of something. What
the name refers to may change over time, but the identity remains the same. This is used in Storm to
implement lazy loading and dynamic recompilation of programs, for example. Each function corresponds
to one RefSource
that refers to the function's identity. The contents of the RefSource
is
initially just a stub function that compiles the function. When this happens, the Content
of the
RefSource
is replaced with a new instance of the Content
class that contains the code of the
compiled function. However, since the RefSource
is the same, all references to it are updated to
refer to the new Content
.
The RefSource
type itself is abstract due to the title
member. The title
member provides a
string representation of the identity of the RefSource
. The Intermediate Language provides one
default implementation of a RefSource
called StrRefSource
, which simply identifies the
RefSource
using a string. Storm as a whole provides additional overloads, in particular
core.asm.NamedSource
, which uses a Named
object to provide the title
.
Reference
Finally, there are two types of references that may refer to a RefSource
. These are
core.asm.Ref
and core.asm.Reference
. The Ref
type represents a
lightweight reference. This means that Ref
simply contains a pointer to the RefSource
, so that
it is able to retrieve the address and the title on demand. The Reference
type, on the other hand,
represents a robust reference. It is robust in the sense that it registers itself with the
associated RefSource
so that it gets notified whenever the Content
of the RefSource
changes.
This means that it is possible to create a sub-class to Reference
and overrode the moved
member
to get notifications about changes to the RefSource
. This is the mechanism used by Storm to
dynamically re-link the program whenever RefSources
are modified.
This means that one typically uses the lightweight Ref
objects during code generation, since they
are lightweight and quick to move around. Then, at the last stages of code generation, one converts
the Ref
object into a robust Reference
subclass, so that the created data structures can be
updated whenever the associated RefSource
are updated.