A common runtime environment / object model for AOT compiled languages?

Something that I’ve been pondering for a while: Does the idea of a common runtime environment & object model for ahead-of-time compiled languages make sense?

Let me explain what I mean by “runtime environment” - I’m not talking about a replacement for glibc or anything on that level. Rather, I’m thinking of something more like Java but without the interpreter or JIT, based on LLVM.

This runtime environment would theoretically allow different languages with different semantics to interoperate in a single environment. Code written in language A could invoke methods on an object written in language B. The two languages might have different algorithms for method resolution, but the interface to that algorithm would be the same. This means that objects from either language would have to start with a common header struct. (Languages which are outliers might have to add special syntax to interoperate with the common object model or use some kind of FFI - that’s OK. But the common case should require no special syntax.)

The environment would also support the dynamic loading of modules, and reconciling of types - so if the main program has a definition of type T, and a loaded module also has a definition for T, the module initialization code would be smart enough to merge the two definitions - so that objects of type T created by the plugin would be the same type as objects of type T created by the main program.

The runtime environment would also specify support for both reflection and garbage collection - that is, a programmer writing in language A could query information about methods for an object written in language B. Of course, in order for this to work the reflection system would have to be flexible enough to represent types from a variety of languages, but DWARF manages to (mostly) achieve this today, so it’s not completely out of the question.

Speaking of DWARF, I would suggest that the runtime environment define its own debugging metadata format, since most of the structural information about types is captured by the reflection system already - mainly what you’d need is the line number information and information about local variables.

There would of course be various standard libraries for common tasks that are compatible with this runtime environment, but I’m going to declare those out of scope for the moment, to prevent the discussion from ranging too far afield. At the same time, you’d probably want a few core types (like String) to be standardized.

This runtime environment would be mainly targeted at AOT (Ahead Of Time) compiled languages. That is the primary distinguishing feature compared to something like the JVM or CLR.

Given that brief description, my questions to the forum are:

  • Is something like this technically feasible? Or is it too ambitious?
  • Is this something that people would use? Would it be viable as an open-source project?
  • Would the standardization of method dispatch and other low-level interface details create too much of a performance impact? My goal is for something that can compete with Java and C++ from a performance standpoint.
    My motives for asking this are due to the fact that I like experimenting with languages and writing compilers, but certain tasks are simply too large for one person to do by themselves. If I could split off part of my own project into something that multiple people would be interested in working on (for their own self-interested reasons), it would be of immense benefit to me. I would also like it if other people doing language experimentation based on LLVM didn’t have to struggle with these issues either, which would in turn encourage more people to do innovative things with LLVM.