hg: valhalla/valhalla/langtools: BytecodeMapping generation fixes:

Peter Levart peter.levart at gmail.com
Tue Jan 6 19:50:39 UTC 2015


I see, thanks.

The problem with my Box<any T> example as it came to me after the fact 
is that the T=reference specialization is not a specialization at all - 
the javac generated template is used as is for the T=reference case 
unchanged - therefore it contains the __WhereVal(T) method too and javac 
is right to refuse to compile a call to it. Perhaps, if I reversed the 
parts and put __WhereVal(T) method in private superclass and 
__WhereRef(T) method in subclass, then it should work for T=reference 
case and probably also for T=primitive case if __WhereRef(T) methods are 
not included in primitive specialization and javac allows me to call the 
inherited method from superclass.

Will try that.


Regards, Peter

On 01/06/2015 07:09 PM, Brian Goetz wrote:
> Also, note: the __WhereRef(T) syntax is intended to be a quick hack, 
> this is definitely not where the syntax is going.  It was just what 
> was easy to implement quickly.
>
> On 1/6/2015 12:51 PM, Maurizio Cimadamore wrote:
>> As you found out, layering support is still missing from the prototype;
>> you have ability to declare RefOnly/ValOnly members but that's pretty
>> much about it. It's still quite powerful though, albeit some things
>> don't work automagically as you'd expect. What you are looking for is a
>> way to write implementation by parts - and that's the bit that's missing
>> from the current implementation (we have a rough proof of concept that
>> does that, but it's not very polished, and the syntax that it supports
>> is very different from the one described in the document).
>>
>> Maurizio
>>
>> On 06/01/15 17:27, Peter Levart wrote:
>>> On 01/06/2015 02:00 PM, maurizio.cimadamore at oracle.com wrote:
>>>> Changeset: 8331682af2ed
>>>> Author:    mcimadamore
>>>> Date:      2015-01-06 12:54 +0000
>>>> URL:http://hg.openjdk.java.net/valhalla/valhalla/langtools/rev/8331682af2ed 
>>>>
>>>>
>>>>
>>>> BytecodeMapping generation fixes:
>>>> * missing BMA for eq/ne any comparisons nested within logic operators
>>>> &&/||
>>>> * missing BMA for field/method access immediately following a
>>>> constructor call
>>>> * refactor Items code in order to avoid cast to AnyItem in order to
>>>> access type info associated with a given item
>>>> * added tests
>>>>
>>>> ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
>>>> ! src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java
>>>> + test/tools/javac/valhalla/typespec/items/tests/TestBinary.java
>>>> ! test/tools/javac/valhalla/typespec/items/tests/TestInstanceof.java
>>>> ! test/tools/javac/valhalla/typespec/items/tests/TestNew.java
>>>>
>>>
>>> Thanks Maurizio,
>>>
>>> It works now. But I have another (seems like javac) problem. Since
>>> layers are not yet implemented (or I just can't seem to figure out how
>>> to use them), I tried to use __WhereRef(T) and __WhereVal(T) with
>>> inheritance to simulate them. My 1st goal was to create a Box<any T>
>>> class that would implement Object.equals() in a way that would use
>>> Objects.equals() for reference T and '==' for value T. Here's what I
>>> came up with:
>>>
>>> // the Ref "layer"
>>>
>>> abstract class RefBoxBase<any T> {
>>>
>>>     public abstract T get();
>>>
>>>     public __WhereRef(T) int hashCode() {
>>>         return Objects.hashCode(get());
>>>     }
>>>
>>>     public __WhereRef(T) boolean equals(Object obj) {
>>>         return (this == obj) ||
>>>             (obj != null &&
>>>                 this.getClass() == obj.getClass() &&
>>>                 Objects.equals(this.get(), ((RefBoxBase<T>) obj).get())
>>>             );
>>>     }
>>> }
>>>
>>> // the Val "overlay"
>>>
>>> public final class Box<any T> extends RefBoxBase<T> {
>>>
>>>     private T value;
>>>
>>>     public Box(T value) {
>>>         this.value = value;
>>>     }
>>>
>>>     public Box() {
>>>         // leave default value
>>>     }
>>>
>>>     public T get() {
>>>         return value;
>>>     }
>>>
>>>     public __WhereVal(T) int hashCode() {
>>>         return 0; // don't know yet how to do something meaningful here
>>>     }
>>>
>>>     public __WhereVal(T) boolean equals(Object obj) {
>>>         return (this == obj) ||
>>>             (obj != null &&
>>>                 this.getClass() == obj.getClass() &&
>>>                 this.get() == ((Box<T>)obj).get());
>>>     }
>>> }
>>>
>>>
>>> And the test:
>>>
>>> public class Test {
>>>     public static void main(String[] args) {
>>>         System.out.println(new Box<int>(1).equals(new Box<int>(1)));
>>> // this compiles fine
>>>
>>>         System.out.println(new Box<String>("a").equals(new
>>> Box<String>("a"))); // compilation error
>>>     }
>>> }
>>>
>>> src/util/Test.java:6: error: bad receiver type Box<String> in
>>> restricted method call
>>>         System.out.println(new Box<String>("a").equals(new
>>> Box<String>("a")));
>>>                                                       ^
>>> Note: src/util/RefBoxBase.java uses unchecked or unsafe operations.
>>> Note: Recompile with -Xlint:unchecked for details.
>>> 1 error
>>>
>>>
>>> It's true that Box.equals() is restricted for Val receiver, but I
>>> thought that RefBoxBase.equals() would be "uncovered" in this case an
>>> inherited in Ref specialization.
>>>
>>>
>>>
>>> Regards, Peter
>>>
>>>
>>



More information about the valhalla-dev mailing list