IDL interfaces
Jonathan S. Shapiro
shap@eros-os.org
Tue, 4 Jul 2000 09:57:32 -0400
[David, Alan: you may want to join the eros-arch list, if only temporarily.
For instructions see http://www.eros-os.org/project/mailing-lists.html]
> Also, what are your thoughts on an interface definition language / and
> query interface style system?
I must preface this by saying that IDLs are something I don't know a lot
about, and that much of my thoughts on what an EROS IDL needs to express are
hazy. Therefore, I hope that people will help challenge these comments and
use them as a seed for discussion. They relate to previous comments that I
made to Alan Karp about practical limits on the number and variety of
capability types per object.
Several times over the last decade I have looked at various IDL languages,
starting with the Sun RPC language. It's an issue that seems to keep popping
up. Most recently, when Bryan Ford got into building what he called a COM
model for Fluke he and I had some discussions. These later prompted me to
look at David Beazley's SWIG system.
Each time I have looked, I've groaned at the pain of getting code generated
that would match up efficiently with the EROS IPC system. This is a very
minor objection. I kept deferring because none of the EROS capability
invocations really call for a stub generator. There are no complex
pointer-linked structures to move around; mostly it's a matter of getting
the arguments to the stub procedure arranged in the right order. This was
easier to do when there were fewer capability types, and it would now be
very helpful to have an IDL-based stub generator for any number of reasons.
But the more compelling reason that I haven't already adopted an IDL system
is my discomfort with the expressiveness of the input languages. the Sun RPC
system is procedure oriented; this is clearly not helpful enough. Most of
the CORBA-like systems are object-oriented. Surprisingly, this is not
helpful either. The following digression on design patterns may help shed
light on why this is so.
EROS isn't really an object-oriented system, because the objects don't have
inheritance. While it *is* an object based system, it isn't like most
others. An EROS process can export any arbitrary set of interfaces, and
these may or may not correspond to object interfaces in a simple way. Let me
take a digression to describe the two common design patterns for interfaces
to EROS processes.
** One object, different interface thinnings
In this pattern, there is a single conceptual object that has a set of
operations. Different interfaces (represented by different capabilities)
export different subsets of these operations. Note, however, that the
operation codes (the number corresponding to the function being invoked) are
not assigned on a per-interface basis. The read-only interface to a page
uses the same function number for "read" as the read-write interface; it
just doesn't export the operations that permit write authority.
While you could pretend that these are just different objects, this becomes
rapidly inconvenient. In particular, more powerful interface variants often
want to return capabilities to less powerful interface variants, and you'ld
like to be able to type check that fact. It helps to know that the two
objects are really the same.
I have not yet encountered an IDL input language that makes the expression
of this natural.
** Many Objects
The second design pattern is to export both an object and it's metaobject
from a single process, or several instances of the same object. For example,
the file system object conceptually exports both a set of filesystem related
interfaces and also a file interface.
I'm not aware of any special difficulties that this causes.
** Historical interfaces
An EROS process may start in either of the two design patterns above, and be
forced to implement variant interfaces over time for reasons of backward
compatibility. This complicates matters considerably.
Finally, mapping the interface to the IPC isn't trivial. Someone (Kragen?)
has already noted that the manual describes the protocol in terms of what is
transmitted in R0, R1, etc. rather than what is transmitted in EAX. On each
architecture there is some physical register corresponding to R0, but you
should think of this as a last-minute macro-substitution at the bottom-most
layer of the assembler. The specification of the bottom-level IPC
representation can be made independent of the target architecture.
Regrettably, the stub generator needs to know the mappings on a
per-architecture basis, because they overlap. On the x86 in particular,
registers are so tight that load and spill code must often be generated in
order to get everything into the right places. This is actually a serious
deficiency in the IPC spec, and it means that the stub generator is (a) not
trivial and (b) must target assembler, not C.
In short, it's all rather a serious mess.