Okay :-) I was more or less just playing devil’s advocate here, trying to make 
us think through all possibilities.

> On Jan 12, 2016, at 4:06 AM, Sundararajan Athijegannathan 
> <sundararajan.athijegannat...@oracle.com> wrote:
> 
> Also, we have to recall ConsString as optimization to represent JS "string" 
> primitive has caused lot of pain.. (internal type hiding, conversion in 
> places...). We fixed number of issues after introducing ConsString. If we 
> were to introduce JSNumber type, we may have to do similar conversions (like 
> what is being done for ConsString) everywhere -- to hide and present Number 
> to the java side...
> 
> I agree with Hannes that it is important to use java.lang.* primitive 
> wrappers being used to represent JS primitives for seamless integration.
> 
> -Sundar
> 
> On 1/12/2016 4:10 AM, Hannes Wallnoefer wrote:
>> 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