yesterday's entry I didn't get to the stuff that kept me going in circles
last week. I had decided on the mixed model a few months ago, but as usual the
devil is in the details.
Initially I wanted to keep the map.xml format more or less the same and I
think that put me on the wrong track. Let's start by taking a look at some of the
current map.xml features. Within the <class> tag there are <constructor> and
<method> tags. These can contain several different child tags:
The thing to note is that some of the remapping implications are still
handled manually in this scheme. For example, the <invokevirtual> of
Object.hashCode has to check for string instances. This information can be
derived from the remapping file and it shouldn't be necessary to do this
I didn't really like the <invokespecial> and <invokevirtual> constructs and I
explored the idea of only having a <body> tag that contains the method body.
However, it soon became clear that that wouldn't be enough. For example, the
implementation of java.lang.Object.clone needs to call the protected method
System.Object.MemberwiseClone and this is only allowed in subclasses. So it
wouldn't be possible to generate a verifiable helper method for that.
The obvious solution (in hindsight) came to me when I realised that there are
actually two types of "subclasses" of java.lang.Object, the ones that really
extend java.lang.Object (our generated .NET type) and the ones that don't (e.g.
arrays, System.String and all other .NET types). I knew this before, of course,
but I was trying to make the model too general. After this realisation, it
became obvious that every method should have a <body> and an <alternateBody>
After I've modified the remapping engine to automatically handle all the
overridden method implications, the <alternateBody> construct will not be needed
for many methods. I think only for Object.clone and Object.finalize and both
will be trivial. The <alternateBody> for clone will throw a
CloneNotSupportedException (it could also check if the object implements
ICloneable and if so, invoke that Clone method, but does this really help?) and
the <alternateBody> for finalize will simply be empty, since there is no good
reason to ever explicitly invoke the Finalize method of a .NET type.
As an aside, I'm also going to remove the <redirect> construct, because it
doens't really add any value. It's just as easy to have a <body> with a <call>.
I'm not clear on the performance implications of these changes. In the
existing model, many of the remapping constructs are inlined, but in the new
model they won't be, invokespecial will end up calling the real method in
the new classes and invokevirtual will call the static helper method.
This will probably be slightly slower, but I think the other advantages easily
Another advantage of this scheme that I didn't yet mention is that reflection
on remapped methods is now trivial. Currently, the following program doesn't work
on IKVM, in the new model the call would simply end up at the static helper
method for clone:
public static void main(String args) throws Exception
m = Object.class.getDeclaredMethod("clone", new Class);
System.out.println(m.invoke(args, new Object));
BTW, I originally tried this by getting the public clone method on the array
class, but oddly enough on the Sun JVM array types don't appear to have a public
clone method (even though you can call it just fine!).
I apologize for the lameness of this, but the comment spam was driving me nuts.
In order to be able to post a comment, you need to answer a simple question. Hopefully this question
is easy enough not to annoy serious commenters, but hard enough to keep the spammers away.
Anti-Spam Question: What method on java.lang.System returns an object's original hashcode (i.e. the
one that would be returned by java.lang.Object.hashCode() if it wasn't overridden)? (case is significant)
Powered by: newtelligence dasBlog 2.3.12105.0
© Copyright 2017, Jeroen Frijters