Jim Coker Andersen Consulting 100 South Wacker Drive Chicago, IL 60606 312-507-4983 email: jcoker@andersen.com Abstract: This workshop position paper suggests further requirements for an object engine as described in the report from the OOPSLA '94 Object Engine workshop. Some proposals are made based on these requirements as well as others from the workshop report. The proposals are for a typed object model that uses a metaclass structure for holding language-specific behavior, and an object engine kernel structured as a byte-code interpreter. The Java virtual machine is used as a model. Current Work and Motivation: As part of the development of an object-oriented CASE tool that incorporates KBSE (Knowledge Based Software Engineering) concepts, we are developing a strongly-typed object-oriented programming language, Argo, that is based on the ODMG's ODL, and C++, and incorporates features from various other languages, notably Eiffel and ADL. The goal is to provide a language that is appropriate both for use by object-oriented designers, and implementors of such designs. Argo has a class-based object model, with an attribute and relation model for specifying the structure of a class' data members; and class invariants and member function pre- and postconditions for specifying behavior. Attribute and relation values are accessed through automatically generated member functions. Pairs of relations can be linked together as inverses of each other; the accessors for those relations automatically maintain referential integrity. Some of the language features that we plan to explore in the future include event-base broadcasting of method calls, an object model that separates interfaces from implementations, and support for distribution and persistence. It has been suggested that instead of C++, the Argo tools could generate Java byte codes, and use the Java interpreter to run Argo programs. This would be a big step forward in terms of runtime sophistication, with such features as built-in support for threads and garbage collection, but certain object model assumptions, such as method resolution, are built into the Java VM. So more advanced features that are not provided will have to be built on top of existing ones, just as in the case for generating to C++, but the lower level of byte codes. Though we are committed to generating C++ for the short term, it is clear that generating for a more appropriate excecution environment would be a superior solution. This is how we see the Object Engine; it would be an envionment in which we could implement object-oriented languages. An Object Engine Proposal The requirements and issues for an object engine are divided into three sections: - a base object paradigm - an intermediate representation - an object engine kernel Base Object Paradigm In terms of a base object paradigm, the key is to provide a base flexible enough to support different language syles, without becoming so general as to prohibit efficient implemention, or suitable run-time support. Some of the language features that one should be able to explore are: - formal specification, such as that provided by Eiffel - different models for exceptions - support for parametric polymorphism - separation of type and implementation inheritance - static vs. run-time type determination - run-time modification of object type information - type restrictions on the parameters of parametrized classes Many important requirements are mentioned in the '94 workshop report: - objects should be accessed only by member functions as suggested by encapsulated aspects, - everything as an object, including classes, messages, and contexts - reflective capabilites (supported by the above) - instance specialization - concurrency support An important issue that should be fully explored is how objects are typed, and how that information is used. This section proceeds by discussing various reqirements related to typing, then makes a proposal to satisfy those requirements. An object's interface should be composed only of methods (or member functions, in C++ terms), without any explicit notion of state. Thus the specification of an object's interface would be a set of understood methods, each with a list of typed arguments and a typed return value. The types may refer to other defined types, or an undefined any type. This approach simplifies typing rules, and allows languages to either have regular instance variables (by generating accessor function calls on access and assignment) or use other approaches, such as attributes and relations. I don't think it is necessary to provide explicit support for bi-directional relations. Even though they are very useful, such features are more appropriately a part of the language being implemented. Similarly to IDL, interface inheritance should be kept separate from implementation inheritance. Java's use of interfaces with classes shows a way that this somewhat subtle notion can be incorporated into a more traditional class-based object model. Method resolution and type checking (static vs. runtime) should be determined by the language, not fixed by the base pardigm. For example, a strongly-typed language may predetermine the method to call and only require an offset cacluation, like C++ vtables; an untyped language may need to call a routine to search for a method body, like Smalltalk. An approach to implementing such flexibility, as mentioned in the workshop report, would be to use metaclass objects to hold this behavior. Combining the above notions suggests the following base object paradigm: A typed, class-based object model, with interfaces for specifying types, classes of objects that implement interfaces, and metaclass objects for storing type information and determining run-time meta-level object behavior. The intention of this structure is not to prohibit the implementation of prototype-based languages, but to provide an infrastructure for flexible typing and behavior modification. Classes exist to group objects that satisfy some set of interfaces, and metaclasses exist to provide type and messaging behavior. Secondary objects of interest at the meta-level would include objects for classes (similar to Smalltalk, but much more lightweight), messages, and blocks of code. Intermediate Representation This paper proposes the use of byte codes for representing program code, and some storage format for metaclass information. During execution, metaclasses would be automatically instantiated as needed. This suggests a simple persistence mechanism for metaclass information. There would be two sorts of meta information and behavior associated with any object: statically determined type information, and meta-level behavior for determining runtime execution semantics such as method lookup. In terms of the suggested base paradigm, this could be implemented by having a standardized metaclass protocol for storing and accessing type information, method lookup, and other meta-level behavior. Each language implemented for the object engine would provide metaclass objects that implement the standard protocol. The Java language has an implementation based on a byte code interpreter with run-time access to class definition information. The object engine would be similar, but without hard-coded assumptions for method lookup and type checking. The '94 workshop report mentions using language expression objects for an intermediate representation. The byte-code model suggested here is different in how information is organized: In this proposal, regular program code is compiled into byte codes, and language-specific behavior is handled by metaclasses. For langauge expression objects, the two seem to be combined. Object Engine Kernel Based on the general structure outlined above, the basic implementation of the object engine whould be a kernel with essential features, such as byte-code interpretation, memory management and thread support. New features could be added through extensions to the kernel, or embedded as part of metaclass behavior. This would encourage experimentation without hindering basic development of the kernel. Some external modules that could be added include various sorts of compilers (either back into byte codes, or machine code) and support distribution, persistence or security. There should be a format for pre-compiled libraries of objects, to encourage reuse of language-independent libraries. And for convenience and integration, one should be able to access precompiled C++ libraries. Conclusion The development of an Object Engine as an execution environment for object-oriented languages provides numerous advantages: - For the language designer, the ability to explore language designs without having to devote inordinate amounts of resources to implementation - For the compilation expert, the ability to explore compilation techniques without having the result tied to a specific language. - For the software developer, the ability to develop libraries, frameworks and programming tools that are language independent The design of this engine must walk a very clever line between providing sufficiently complete and appropriate built-in features for productive language implementation but without becoming overly complex or restrictive. This proposal suggests a structure for the object engine based on the interpretation of byte codes and runtime availability of type information. It is similar in structure to the Java virtual machine, which is itself based on previous byte-coded environments. Though the Java VM doesn't provide the amount of runtime support or flexiblity needed for a general purpose object engine, it has been sucessfully implemented on a number of platforms, and provides a good model for further development. References The Object Database Standard, ODMG-93 R. Cattell ed. Morgan Kaufman, 1994 The Annotated C++ Reference Manual M. Ellis and B. Stroustrup Addison-Wesley, 1990 Smalltalk-80: The Language and its Implementation A. Goldberg and D. Robson Addison-Wesley, 1983 Eiffel, The Language Bertrand Meyer Prentice Hall, 1992 ADL - An Interface Definition Language for Specifying and Testing Software Sriram Sankar and Roger Hayes Proc. of the Workshop on Inteface Definition Languages Jeannette Wing editor SIGPLAN Notices 29:8, August 1994 The Java Programming Language: A White Paper Sun Microsystems http://java.sun.com/documentation.html First Draft: The Java/HotJava Programmer's Guide Sun Microsystems http://java.sun.com/documentation.html