Am 2016-01-11 um 19:45 schrieb Attila Szegedi:
Specifically in relation to the remark that JSType.isNumber check is getting 
long… I think we could be even more conservative if we wished to, namely only 
recognizing Integer and Double as wrapped numbers. Within Nashorn, byte, short, 
float, and long don't occur naturally, only int and double occur. Their 
wrappers (Byte, Short, etc.) therefore also can’t appear. The only way to 
introduce them is through POJO methods with such return types (e.g. 
Byte.valueOf()). I’m not sure we’re under an obligation to consider those 
equivalent to JS numbers. We could declare that Byte, Short, Float, and Long 
are not numbers just host objects, albeit ones that JSType.toNumber understands.

I guess we could do that, but we would (IMO) needlessly change the rules we set up with Nashorn in JDK8. I think that making Java number primitives equivalent to JS numbers is actually a nice feature. Unfortunately it doesn't really work for longs because JS happens to use double as its only number type, but I don't think that means we should throw out the idea as a whole.

Also, an important point here is that we can't really safely distinguish between primitive number types and object wrappers in Nashorn. A java.lang.Short or java.lang.Float may just be a primitive that happens to be handled in an object context.

Actually, I can take this train of thought in an even more drastic direction. 
Consider this: we would be at liberty to internally box numbers any way we want 
and not rely on java.lang.Double and friends at all! It’s just convenient to 
box JS primitive number values (and booleans, BTW) using readily available 
java.lang.* boxes, but we could have a NashornNumber and NashornBoolean classes 
for internal boxing of JS primitive numbers and booleans, when they need to be 
boxed. Then we could even allow ourselves to not recognize any Java primitive 
wrapper objects as special cases of JS primitive values at all. The thought is 
actually not so far fetched in the sense that we already have ConsString too, 
an alternative internal string representation that is not a java.lang.String. 
We’d just have to take care that such NashornNumber boxes are handled in all 
places where ConsString is handled and converted into a Double when passing 
from Nashorn to outside world.

That would provide a 100% consistent way of handling wrapper classes: they’re 
all just POJOs at that point, no special treatment whatsoever.

I think what I wrote above also applies here - that seamlessness is actually nice and that we don't really control whether a numeric value from Java is handled as primitive or as wrapper object in Nashorn - that may vary on how JavaScript code was used/optimized/compiled before, what the code does with it, etc.

In Rhino, we had explicit wrapper classes for things to be treated as objects (e.g. a java.lang.Double would be wrapped in a JavaObject wrapper or whatever it was called). Since Nashorn does not use object wrappers, I think it would be hard to distinguish between primitive numbers and object wrappers in this way. It would als feel kind of arbitrary to me.

Hannes

Attila.

On Jan 11, 2016, at 1:48 PM, Hannes Wallnoefer <hannes.wallnoe...@oracle.com> 
wrote:

You are right of course, there needs to be consistency between typeof operator 
and treatment as JS numbers.

This is in fact an unpleasant problem to solve. I've struggled trying to fix 
this without breaking any existing code, but I've come to the conclusion that 
it is not possible. Since we can't treat all Java longs/Longs as JS numbers, 
we'd have to differentiate depending on whether the value can be represented as 
double without losing precision.

In a way we already do this with optimistic types, but I consider it more a bug 
than a feature. It's weird (and error prone) if the return value for a Java 
method returning long is reported as number or object depending on the actual 
value.

So I think the right thing to do is draw a clear line between which Java 
primitive/wrapper types represent JS numbers and which don't. I've uploaded a 
new webrev that implements this:

http://cr.openjdk.java.net/~hannesw/8143896/webrev.01/

Note that the only types to be treated as JS numbers are the direct wrapper 
classes for Java primitives that can be fully represented as doubles. This 
means also things like AtomicInteger and DoubleAdder will be reported and 
treated as objects. I think that's the correct thing to do as they are not 
primitive numbers in the first place. They are still converted to numbers when 
used in such a context in JS. So I think the only place where this change is a 
actually painful/surprising is longs.

Unfortunately the check for number type in JSType.isNumber gets a bit long as 
we have to individually check for all primitive wrapper classes. I've done 
extensive benchmarking and I don't think it has an impact on performance. In 
any way, I wouldn't know how to handle this differently.
Let me know what you think.

Hannes

Am 2016-01-04 um 05:00 schrieb Sundararajan Athijegannathan:
I think I already commented on this webrev -- that we need to cover tests for 
BigInteger, BigDecimal.

Also, I'm not sure linking Double and Int by nashorn  primitive linkers is the right 
solution. AtomicInteger, DoubleAdder etc. are all Number subtypes. We return 
"number" when typeof is used on any Number subtype.
Now, that means JS code will see these as 'number' type objects -- yet 
Number.prototype methods won't work on those!! I know this is hard problem -- 
we also have another (somewhat related) BigDecimal, BigInteger toString / 
String conversion issue. We need to discuss this.

-Sundar

On 1/2/2016 8:29 PM, Attila Szegedi wrote:
+1

On Dec 18, 2015, at 3:54 PM, Hannes Wallnoefer <hannes.wallnoe...@oracle.com> 
wrote:

Please review JDK-8143896: java.lang.Long is implicitly converted to double

http://cr.openjdk.java.net/~hannesw/8143896/webrev/

Thanks,
Hannes


Reply via email to