BGB said:
part of the reason though is I am not really intending to use it for
self-contained apps, but more for app scripting. so it matters more
that the Java<->C interface is good than that the runtime doesn't suck
(sadly... I am still mostly using JNI for a lot of this...).
If you're rolling your own, how about this? Create a utility that
generates a C header file for a specified class, defining it as a C
struct, and when your JVM calls into C, pass a pointer to that struct
instead of an opaque pointer. Your C can now access everything in the
class directly instead of having to use JNI. (Having the header define
function pointers used to call the class's methods would be a further
step.) You lose Java's safety guarantees [1], which are the main reason
that JNI is so clumsy, but to offset that, you have huge gains in
efficiency and ease.
this is an interesting idea...
however, sadly, it would be a little problematic for my current
implementation, which internally uses opaque pointers for classes (for
sake of abstraction/modularity) and also uses relatively more "fluid"
memory handling than C prefers (IOW: physical class layout is not known
until runtime in the current implementation).
actually, the implementation is "transactional", and actually allows
physical class layout to change ("class versions" are used to track the
particular layout of the particular class instance...). class
definition/modification is done via begin/end pairs, where the 'end' may
implicitly commit changes to the class (only partially, as the layout is
not frozen until an instance of the class or a subclass is made, at
which point any further alterations would go into the new 'version').
the above mechanism was used to implement "java/lang/String", which has
a temporary (VM-provided) form initially, but during VM startup the
classfile is loaded and "dropped on top of" the VM defined class (mostly
this was to deal with the problem that otherwise there was no obvious
way to make String loadable, since the constant pool may infact contain
String instances).
this could also allow for "partial classes" (like in .NET), apart from
the lack of any obvious way to handle this in Java.
so, the VM itself uses an interface fairly similar to JNI to access the
OO facilities...
using function pointers to access fields and methods can work though,
where any methods would be exposed directly, and any fields could be
accessed via getters/setters.
at the moment, the main issue is not the C->Java interface, as this
works well enough.
the main issue then is mostly that Java can't so easily access the bulk
of code and API's which exist in C land (this being the vast majority of
the codebase).
I have provided a few JNI alternatives for this part, but technical
issues remain (namely that it is still necessary to write classes with
'native' methods and provide some basic level of boilerplate in most cases).
I don't use JNA as this is not currently implemented and is not any
obviously better for my uses than using JNI, or classes with native
methods and a short-circuit mechanism (as a lighter-weight JNI alternative).
the main cost at the moment is then having to write classes with native
methods for any API calls one wishes to import, and dealing with the
language typesystem mismatches, ... there is no obvious way to export
API's to Java via header-processing, as it would be needed to identify
somehow which functions belong to which class (unless I start using
C-side annotations for this), and classes need to be fully specified and
are limited to a "reasonable" size (64k methods), preventing simple
naive strategies.
apart from using an awkward/nasty strategy (using special classes and
methods to call into C land), there is no obvious way to do
boilerplate-free operation with a standard Java compiler...
another difficulty is that there is no good way to handle
variable-argument calls that doesn't force everything to Object in the
process, which is expensive (creates a bunch of boxed values which turn
into garbage).
....
thinking of it, I may have reason to start supporting function
annotations to identify methods.
for example:
DYC_CLASSAPI("bgb/vm/Foo") void fooMethod(dycThis self, int x)
{
...
}
this would allow some tools to autogenerate classes from C-level
metadata. (however, a few of my tools would need to be modified to
support this feature...).
note: 'dycThis' is already used, and is basically a magic type to
identify that a function is an instance method and expects a 'this'
object to be passed as the given argument (limited to the first function
argument).
DYC_CLASSAPI would be new, and would be analogous to (in C++):
namespace bgb {
namespace vm {
void Foo::fooMethod(int x)
{
...
}
}
}
in a normal C compiler (say, MSVC), it would expand to, say
"__declspec(dllexport)".
in my metadata tool, it could expand to " __declspec(dllexport)
__declspec(dycClassAPI("bgb/vm/Foo")) ".
which would in turn go into a database to be processed by the later tool
(the former tool exists, but the later tool, namely a class-emitter,
would need to be written).
the bigger hassle is that my (slightly hackish) auto-header generator
tool would need to be modified to support this annotation.
1. That is, you gain C's full freedom to scribble all over random bits
of memory.
well, that happens sometimes...
I was checking earlier, and it already seems I implemented most of the
classes for J2ME CLDC already (and actually a few more than this, but a
few holes exist as well...).
I guess I may for now try to get this profile fully implemented.