Nashorn incorrectly binds "this" in constructors created and returned by another function

A. Sundararajan sundararajan.athijegannathan at oracle.com
Fri Oct 31 03:05:06 UTC 2014


+1 on the review request.

-Sundar

On Friday 31 October 2014 03:05 AM, Hannes Wallnoefer wrote:
> It's true that this looks very similar, but it's actually a different 
> issue. I filed a bug for it:
>
> https://bugs.openjdk.java.net/browse/JDK-8062583
>
> Regarding the original bug: I have a fix ready and I'll push it as 
> soon as I get a second review.
>
> http://cr.openjdk.java.net/~hannesw/8062132/
>
> Hannes
>
> Am 2014-10-30 um 20:42 schrieb David P. Caldwell:
>> It looks plausible that this could be related to my Error prototype 
>> issue from a few weeks back.
>>
>> See 
>> http://mail.openjdk.java.net/pipermail/nashorn-dev/2014-October/003581.html
>>
>> So I’d be happy to test the fix, or Hannes, in that message there are 
>> detailed reproduction instructions for a test case I developed.
>>
>> — David.
>> On Oct 30, 2014, at 1:29 PM, Baq Haidri <bhaidri at linkedin.com 
>> <mailto:bhaidri at linkedin.com>> wrote:
>>
>>> Thanks guys, that's great news.
>>>
>>> -----
>>> baq
>>>
>>> ________________________________________
>>> From: Hannes Wallnoefer [hannes.wallnoefer at oracle.com 
>>> <mailto:hannes.wallnoefer at oracle.com>]
>>> Sent: Thursday, October 30, 2014 4:15 AM
>>> To: Marcus Lagergren; Baq Haidri
>>> Cc: nashorn-dev at openjdk.java.net 
>>> <mailto:nashorn-dev at openjdk.java.net>; Mark Pascual
>>> Subject: Re: Nashorn incorrectly binds "this" in constructors 
>>> created and returned by another function
>>>
>>> I have a fix for this and I'm currently running tests to verify it. 
>>> This
>>> will definitley make it into 8u40.
>>>
>>> Hannes
>>>
>>> Am 2014-10-30 um 11:46 schrieb Marcus Lagergren:
>>>> Any bugfix we manage to check in before the end of November will 
>>>> make it into 8u40. Hannes has diagnosed the problem and this is a 
>>>> p2, which is the highest priority of all Nashorn bugs for 8u40 
>>>> right now (no p1s are filed), so I would say it is very likely it 
>>>> will make it into 8u40. Hannes - can you elaborate?
>>>>
>>>> Regards
>>>> Marcus
>>>>
>>>>> On 29 Oct 2014, at 20:09, Baq Haidri <bhaidri at linkedin.com 
>>>>> <mailto:bhaidri at linkedin.com>> wrote:
>>>>>
>>>>> +cpettitt at linkedin.com <mailto:cpettitt at linkedin.com>
>>>>>
>>>>> Hi Jim,
>>>>>
>>>>> Thanks for escalating this so quickly.  This one's a pretty 
>>>>> important for us as LinkedIn is looking to standardize our 
>>>>> production fleet to 8u40 as soon as the GA release is available. 
>>>>>  Can you give us an idea of whether the fix will make it in to 8u40?
>>>>>
>>>>> -----
>>>>> baq
>>>>>
>>>>> ________________________________________
>>>>> From: Jim Laskey (Oracle) [james.laskey at oracle.com 
>>>>> <mailto:james.laskey at oracle.com>]
>>>>> Sent: Monday, October 27, 2014 12:09 PM
>>>>> To: Josh Fleming
>>>>> Cc: nashorn-dev at openjdk.java.net 
>>>>> <mailto:nashorn-dev at openjdk.java.net>; Mark Pascual; Baq Haidri
>>>>> Subject: Re: Nashorn incorrectly binds "this" in constructors 
>>>>> created and returned by another function
>>>>>
>>>>> Just to let you know this has been promoted to 
>>>>> https://bugs.openjdk.java.net/browse/JDK-8062132.  We are 
>>>>> investigating.
>>>>>
>>>>>
>>>>> On Oct 27, 2014, at 4:03 PM, Josh Fleming <jfleming at linkedin.com 
>>>>> <mailto:jfleming at linkedin.com>> wrote:
>>>>>
>>>>>> Hi folks,
>>>>>>
>>>>>> I filed a bug for this on the Oracle site (Review ID: 
>>>>>> JI-9016048), but was told that this list is the best place to 
>>>>>> discuss it.
>>>>>>
>>>>>> So this is a strange one. It seems that the latest release of 
>>>>>> Nashorn incorrectly binds "this" in a constructor function under 
>>>>>> the following conditions:
>>>>>>
>>>>>> * At least 2 level prototype hierarchy (for the sake of 
>>>>>> discussion let's call them Parent and Child)
>>>>>> * Child constructor functions are created and returned by a 
>>>>>> higher order "factory” function
>>>>>> * Child constructors call the Parent constructor, which uses “this”
>>>>>> * Multiple Child prototypes share the same Parent prototype
>>>>>> * The Child prototypes disagree in the *number* of their properties
>>>>>>
>>>>>> When the second Child object instantiates, its constructor calls 
>>>>>> the Parent constructor, whose “this” is incorrectly bound to a 
>>>>>> Parent object rather than the Child.
>>>>>>
>>>>>> Here's the jrunscript reduction (or 
>>>>>> https://gist.github.com/joshvfleming/0539f00dd12392483596):
>>>>>>
>>>>>> // -- BEGIN CODE --
>>>>>> function subclass(parentConstructor, proto) {
>>>>>> function C() {
>>>>>>   parentConstructor.call(this);
>>>>>> }
>>>>>>
>>>>>> C.prototype = Object.create(parentConstructor.prototype);
>>>>>>
>>>>>> for (var prop in proto) {
>>>>>>   if (proto.hasOwnProperty(prop)) {
>>>>>>     C.prototype[prop] = proto[prop];
>>>>>>   }
>>>>>> }
>>>>>>
>>>>>> return C;
>>>>>> }
>>>>>>
>>>>>> var Parent = function() {
>>>>>> this.init();
>>>>>> };
>>>>>>
>>>>>> Parent.prototype = {
>>>>>> init: null
>>>>>> }
>>>>>>
>>>>>> var Child1 = subclass(Parent, {
>>>>>> prop1: 1,
>>>>>> init: function() {
>>>>>>   print('!!! child 1');
>>>>>> }
>>>>>> });
>>>>>>
>>>>>> var Child2 = subclass(Parent, {
>>>>>> init: function() {
>>>>>>   print('!!! child 2');
>>>>>> }
>>>>>> });
>>>>>>
>>>>>> new Child1();
>>>>>> new Child2();
>>>>>> // -- END CODE --
>>>>>>
>>>>>> Expected output:
>>>>>>
>>>>>> !!! child 1
>>>>>> !!! child 2
>>>>>>
>>>>>> Actual output:
>>>>>>
>>>>>> !!! child 1
>>>>>> script error in file 
>>>>>> scripts/nashorn_this_binding_bug_reduction.js : TypeError: null 
>>>>>> is not a function in 
>>>>>> scripts/nashorn_this_binding_bug_reduction.js at line number 19
>>>>>>
>>>>>> The script blows up at line 19 (see above or 
>>>>>> https://gist.github.com/joshvfleming/0539f00dd12392483596) when 
>>>>>> the Parent constructor tries to call "this.init()". This function 
>>>>>> has been overridden in the Child objects that we instantiate at 
>>>>>> the bottom, but Nashorn incorrectly binds "this" to the Parent 
>>>>>> object, whose “init” is bound to "null" instead of an "init" 
>>>>>> function.
>>>>>>
>>>>>> One especially strange and interesting aspect of this is that it 
>>>>>> depends on the relative number of properties of the two Child 
>>>>>> prototypes. The reduction above fails because Child1 has the 
>>>>>> "prop1" property, but Child2 has none. If you add any property at 
>>>>>> all to Child2, the error goes away. If you add still another 
>>>>>> property, the error returns.
>>>>>>
>>>>>> Affected JRE:
>>>>>>
>>>>>> Java version "1.8.0_25"
>>>>>> Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
>>>>>>
>>>>>> This bug appears to be a regression, as the following older JRE 
>>>>>> returns the "Expected" output:
>>>>>>
>>>>>> java version "1.8.0_05"
>>>>>> Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
>>>>>> Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)
>>>>>>
>>>>>> We’re stuck on 1.8.0_05 at this point, because one of our 3rd 
>>>>>> party libraries uses this inheritance pattern.
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>>
>>>>>> jf
>>>>>>
>>>
>>
>



More information about the nashorn-dev mailing list