The active object wrapper that MOZ uses is one of the more complicated pieces of code in the MOZ, as well as the piece that may seem oddest to users of other object oriented langauges. Also, it is the largest piece of ex-db code.
The active object wrapper is actually a procedure that is passed an object. It returns an object record with full capabilities. An object record consists of a wrapper procedure, the objects Oz name, and a capability set. All the wrapper procedure does is pass its one argument to a port (an Oz port, not a TCP/IP port).
It's what's at the other end of that port that's interesting. A thread is created to process the stuff passed in the port. Note that this means that each object has exactly one thread associated with it, and this thread is the only one that ever gets to affect the object directly. This make things much easier as far as multi-threading issues go, as no locking needs to be done within object methods.
This wrapper also gives insultion: no-one ever sees the object directly except this thread, and this is what allows the capability security system to work.
Also, the thread can do other processing besides just calling the method it has been passed. The most important part of this processing is capability processing. Basically, what's passed to the port is not the method name, it's a record with an Oz name for a label. This label is used to key a dictionary, and if a method name associated with it is found, that method is called, if not, an error is returned. For more information, see See Capability Implementation.
Another, much cooler, thing that the wrapper thread does is handle
upgrade requests. upgrade is a virtual method, in that it is called
just like any other method in the wrapper, using an Oz name capability,
but it doesn't exist in the object, rather it exists in the wrapper. An
upgrade call takes a class name and actually swaps out the object it's
wrapping for one of that class! It calls toRecord
and fromRecord
to
make sure information is preserved, and lets the Storage object know the
new class name. Then it just goes back to processing the port like
nothing happened, and from the point of view of every other object in
the mud, nothing did!
There are a couple of other miscellaneous things the wrapper does. In
particular, it inserts capability information into a toRecord
call and
extracts it from a fromRecord
call.
When a new object is created, the capability dictionary is built using
the class's methodList feature, with the addition of the special
capability 'upgrade', and a bunch of new Oz names. In many cases, these
are then overwritten by a fromRecord
call.
The object itself will often need to know about its wrapper and capabilities, so that it can inform other objects. This is handled by a method on every object in the MOZ called activeObjectInform, which takes those two pieces of information as arguments, generally to store on attributes. This method is called every time wrapper information is changed.
The Storage object is also informed of this information at the same time.
See General Class Issues.