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 >> >> >