What can we improve in JSR292 for Java 9?

Jochen Theodorou blackdrag at gmx.org
Thu Mar 5 15:50:13 UTC 2015


Am 05.03.2015 11:09, schrieb Peter Levart:
> On 03/05/2015 04:09 AM, Jochen Theodorou wrote:
[...]
>> public class Foo {
>>   public Foo(String s, Integer i){}
>>   public Foo(Integer s, Object o){}
>> }
>>
>> public class Bar extends Foo {
>>   public Bar(def a, def b) {
>>      super(a,b) // call with runtime types here
>>   }
>> }
>>
>> I cannot express super(a,b) using method handles
[...]
> Here's an idea. Let Groovy compile Foo to the following Java equivalent:
>
> public class Foo {
>      public Foo(Onject p1, Object p2) {
>          super();
>          invokedynamic _init(p1, p2);
>      }
>
>      private void _init(String s, Integer i) {
>          // the body of constructor for (String, Integer)
>      }
>
>      private void _init(Integer s, Object o) {
>          // the body of constructor for (Integer, Object)
>      }
> }

ok, sorry that I did not mention this contraint... Bar is in Groovy, Foo 
is written in Java. Meaning we have no control over Foo. Take for 
example BigDecimal instead of Foo.

[...]
> So what we might need (also for other purposes like de-serialization) is
> a special kind of private void instance initialization methods that are
> treated specially by verifier and javac. The rules for such methods
> could be as follows:
>
> - they are treated like constructors regarding assignment to final
> instance fields
> - they can not be called from normal code except from constructors of
> the same class that calls: super constructor followed by a call to one
> of those special initialization methods. For example:
>
> public class Bar extends Foo {
>
>      private final int val;
>
>      public Bar(String s, int val) {
>          super(s);
>          // call to special @init method can only appear immediately
> after call to super constructor (verifier checked)
>          initVal(val); // ...together they have the effect of calling
> any this(...) constructor
>
>          // ...so this is not allowed by javac
>          this.val = 42;
>      }
>
>      @init private void initVal(int val) {
>          this.val = val; // allowed and required (like in constructor)
>      }
>
>      public void normalMethod() {
>          initVal(42); // not allowed by javac or verifier
>      }
> ...
>
> Those special @init methods could be invoked using reflection with
> overridden access checks (setAccessible(true)) and looked up as method
> handles using privileged Lookup only.

hmm... might be an idea worth of investigation. I don't know if it can 
be done, because of the verifier. The biggest problem in the current 
logic is that you basically do an invokespecial with a kind of class 
reference loaded by an aload 0. But this is not a normal "this", like 
you normally have. The sole purpose of it (afaik) is to call the super 
constructor. Any other call on this will cause problems. Your idea 
would, if we don't want to change the verifier, thus require an 
initialized class instance on the stack... which we won't get before 
calling super. But calling super is basically what we want to do.

Btw, besides the special logic for final assignment... not all versions 
enforce that in the JVM. Reflection and Unsafe are often ways around 
that. But there is also the special logic for final fields and 
concurrent publication in the current memory model to consider here. I 
would not want to loose that.

There is of course that internal deserialization logic Java has to 
create a "blank" instance. Maybe that could be used to have a kind of 
"valid" object to make calls on... But I am really not sure about the 
implications of that.

In the end I really wonder if it is possible to implement these kinds of 
things without a change to the Verifier. If the Verifier can be tweaked 
a bit, then there should be a solution

bye blackdrag


-- 
Jochen "blackdrag" Theodorou - Groovy Project Tech Lead
blog: http://blackdragsview.blogspot.com/
german groovy discussion newsgroup: de.comp.lang.misc
For Groovy programming sources visit http://groovy-lang.org



More information about the mlvm-dev mailing list