# HG changeset patch # User hannesw # Date 1382093421 -7200 # Node ID 66d27c77b455978ac5b5e816dfa314d60238b240 # Parent a2065f67857c95f2e71e70969b6af5fa0da71169 8026805: Array.prototype.length doesn't work as expected Reviewed-by: sundar, lagergren diff -r a2065f67857c -r 66d27c77b455 src/jdk/nashorn/internal/objects/Global.java --- a/src/jdk/nashorn/internal/objects/Global.java Thu Oct 17 17:33:16 2013 +0200 +++ b/src/jdk/nashorn/internal/objects/Global.java Fri Oct 18 12:50:21 2013 +0200 @@ -1665,9 +1665,9 @@ final ScriptObject stringPrototype = getStringPrototype(); stringPrototype.addOwnProperty("length", Attribute.NON_ENUMERABLE_CONSTANT, 0.0); - // add Array.prototype.length + // set isArray flag on Array.prototype final ScriptObject arrayPrototype = getArrayPrototype(); - arrayPrototype.addOwnProperty("length", Attribute.NOT_ENUMERABLE|Attribute.NOT_CONFIGURABLE, 0.0); + arrayPrototype.setIsArray(); this.DEFAULT_DATE = new NativeDate(Double.NaN, this); diff -r a2065f67857c -r 66d27c77b455 src/jdk/nashorn/internal/objects/NativeArray.java --- a/src/jdk/nashorn/internal/objects/NativeArray.java Thu Oct 17 17:33:16 2013 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Fri Oct 18 12:50:21 2013 +0200 @@ -372,9 +372,7 @@ */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object isArray(final Object self, final Object arg) { - return isArray(arg) || (arg == Global.instance().getArrayPrototype()) - || (arg instanceof NativeRegExpExecResult) - || (arg instanceof JSObject && ((JSObject)arg).isArray()); + return isArray(arg) || (arg instanceof JSObject && ((JSObject)arg).isArray()); } /** @@ -403,6 +401,26 @@ } } + /** + * Prototype length getter + * @param self self reference + * @return the length of the object + */ + @Getter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) + public static Object getProtoLength(final Object self) { + return length(self); // Same as instance getter but we can't make nasgen use the same method for prototype + } + + /** + * Prototype length setter + * @param self self reference + * @param length new length property + */ + @Setter(name = "length", where = Where.PROTOTYPE, attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE) + public static void setProtoLength(final Object self, final Object length) { + length(self, length); // Same as instance setter but we can't make nasgen use the same method for prototype + } + static long validLength(final Object length, final boolean reject) { final double doubleLength = JSType.toNumber(length); if (!Double.isNaN(doubleLength) && JSType.isRepresentableAsLong(doubleLength)) { diff -r a2065f67857c -r 66d27c77b455 src/jdk/nashorn/internal/objects/NativeJSAdapter.java --- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Thu Oct 17 17:33:16 2013 +0200 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Fri Oct 18 12:50:21 2013 +0200 @@ -629,7 +629,8 @@ // to name. Probably not a big deal, but if we can ever make it leaner, it'd be nice. return new GuardedInvocation(MH.dropArguments(MH.constant(Object.class, func.makeBoundFunction(this, new Object[] { name })), 0, Object.class), - adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), testJSAdaptor(adaptee, null, null, null)); + adaptee.getMap().getProtoGetSwitchPoint(adaptee.getProto(), __call__), + testJSAdaptor(adaptee, null, null, null)); } } throw typeError("no.such.function", desc.getNameToken(2), ScriptRuntime.safeToString(this)); diff -r a2065f67857c -r 66d27c77b455 test/script/basic/JDK-8026805.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8026805.js Fri Oct 18 12:50:21 2013 +0200 @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8026805: Array.prototype.length doesn't work as expected + * + * @test + * @run + */ + +if (Array.prototype.length !== 0) { + throw new Error("Initial length not 0"); +} + +Array.prototype[3] = 1; + +if (Array.prototype.length !== 4) { + throw new Error("length not updated to 4"); +} + +Array.prototype.length = 0; + +if (Array.prototype.length !== 0) { + throw new Error("length not reset to 0"); +} + +if (3 in Array.prototype) { + throw new Error("array element not deleted"); +}