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