Building your own class objects

Mike Lewis
3/26/97

One way that Legion allows users to provide their own system-level object management services by implementing their own class objects. This note discusses issues related to doing this within the current Legion implementation. The note is written based on the state of the run-time library, the core object implementations, and the Mentat Programming Language (MPL) compiler on 3/26/97.

Current implementation

So far, we have implemented basically one kind of class object, which manages its instances in an unsophisticated manner. The class object is built to use the Legion run-time library's mechanisms for exporting member functions and communicating with other objects. The code is contained in the directory named $LEGION/src/CoreObjects/MetaClasses/Regular. (The "MetaClasses" directory name is misleading, we should and will rename it. It is named as such because eventually, defining a new class will be a matter of implementing a meta-class object which will determine the characteristics of its class object instances, and which will be instantiated to create a new class object with those characteristics. In the current implementation, the concept of a meta-class is implicit.)

The class object directory contains several files that get built into an executable named "ClassObject." We use multiple files to reflect the fact that some parts of a class object's implementation contain details that use the run-time library to allow it to accept member functions (thereby making it a Legion object), while other parts of the implementation contain state information and code that manipulates this state. Typically, this stuff does not really require the Legion run-time library (unless it makes outcalls to other objects). Basically, the ClassObject.trans.[ch] files contain the run-time library specific stuff, and the ClassObject.[ch] files contain the class object specific stuff. The ".trans." part of the name stands for "translated" and reflects the fact that eventually we hope to have a compiler build this part of an object's implementation. For example, we would specify a Mentat class that contains the right functions, and the compiler would generate code to use the run-time library to make its instances Legion objects.

Building a new class object

The best way to build a new kind of class object right now is to copy the code for ClassObject into a new directory, string replace "ClassObject" with some other name (e.g. MyNewClassObject) in the file names and within the files themselves, and reimplement MyNewClassObject.[ch] to provide appropriate instance management policies. The MyNewClassObject.trans.[ch] files should not need to be changed, except for changing "ClassObject" to "MyNewClassObject."

Currently, creating a new instance of MyNewClassObject must be done by running it from the command line because the current implementation assumes that all class objects use the same executable. In other words, you can't use the legion_create_class tool or the Legion.CreateObject() function to create a new MyNewClassObject. (This will be fixed soon.)

Why not use the compiler?

The MPL compiler currently can create Legion objects out of instantiated Mentat classes. However, the compiler does not have any way of allowing the programmer to specify the function numbers of exported functions; instead, it generates them on its own. The run-time library relies on class-mandatory functions being at well-known function numbers (as defined in the file $LEGION/include/legion/sys/UVaL_WellKnownObjectInterfaces.h). If you tried to build a class object by building a Mentat class and using the current compiler, function numbers would not get assigned the right values. Consequently, objects that tried to talk to your class objects would not get through correctly. This is unfortunate because it would be much easier to write class objects in MPL than by using the hand-coded approach described above.