Nashorn incorrectly binds "this" in constructors created and returned by another function
Hannes Wallnoefer
hannes.wallnoefer at oracle.com
Fri Oct 31 19:36:17 UTC 2014
I pushed the fix to JDK9 and 8u40. It should appear in some future early
access release. Please check the "summary of changes" link to see if the
fix is included in a build.
https://jdk8.java.net/download.html
Hannes
Am 2014-10-31 um 14:14 schrieb Josh Fleming:
> That¹s great news. Thanks for looking into it!
>
>
> jf
>
>
>
>
>
> On 10/30/14, 7:15 AM, "Hannes Wallnoefer" <hannes.wallnoefer at oracle.com>
> wrote:
>
>> 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> wrote:
>>>>
>>>> +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]
>>>> Sent: Monday, October 27, 2014 12:09 PM
>>>> To: Josh Fleming
>>>> Cc: 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>
>>>> 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