8147845: Varargs Array functions still leaking longs

Reviewed-by: mhaupt, sundar
This commit is contained in:
Hannes Wallnöfer 2016-01-21 16:31:27 +01:00
parent fff2106bbc
commit fdfdf19e75
4 changed files with 58 additions and 21 deletions

View File

@ -335,7 +335,7 @@ final class FoldConstants extends SimpleNodeVisitor implements Loggable {
break;
case SHR:
final long result = JSType.toUint32(lhs.getInt32() >>> rhs.getInt32());
return LiteralNode.newInstance(token, finish, JSType.isRepresentableAsInt(result) ? (int) result : (double) result);
return LiteralNode.newInstance(token, finish, JSType.toNarrowestNumber(result));
case SAR:
return LiteralNode.newInstance(token, finish, lhs.getInt32() >> rhs.getInt32());
case SHL:

View File

@ -70,7 +70,6 @@ import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.runtime.arrays.ContinuousArrayData;
import jdk.nashorn.internal.runtime.arrays.IntElements;
import jdk.nashorn.internal.runtime.arrays.IntOrLongElements;
import jdk.nashorn.internal.runtime.arrays.IteratorAction;
import jdk.nashorn.internal.runtime.arrays.NumericElements;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
@ -285,7 +284,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
final long newLen = NativeArray.validLength(newLenDesc.getValue());
// Step 3e - note that we need to convert to int or double as long is not considered a JS number type anymore
newLenDesc.setValue(JSType.isRepresentableAsInt(newLen) ? Integer.valueOf((int) newLen) : Double.valueOf((double) newLen));
newLenDesc.setValue(JSType.toNarrowestNumber(newLen));
// Step 3f
// increasing array length - just need to set new length value (and attributes if any) and return
@ -1043,7 +1042,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
if (bulkable(sobj) && sobj.getArray().length() + args.length <= JSType.MAX_UINT) {
final ArrayData newData = sobj.getArray().push(true, args);
sobj.setArray(newData);
return newData.length();
return JSType.toNarrowestNumber(newData.length());
}
long len = JSType.toUint32(sobj.getLength());
@ -1052,7 +1051,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
}
sobj.set("length", len, CALLSITE_STRICT);
return len;
return JSType.toNarrowestNumber(len);
} catch (final ClassCastException | NullPointerException e) {
throw typeError(Context.getGlobal(), e, "not.an.object", ScriptRuntime.safeToString(self));
}
@ -1471,7 +1470,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
final long newLength = len + items.length;
sobj.set("length", newLength, CALLSITE_STRICT);
return newLength;
return JSType.toNarrowestNumber(newLength);
}
/**

View File

@ -791,6 +791,15 @@ public enum JSType {
return Double.NaN;
}
/**
* Convert a long to the narrowest JavaScript Number type. This returns either a
* {@link Integer} or {@link Double} depending on the magnitude of {@code l}.
* @param l a long value
* @return the value converted to Integer or Double
*/
public static Number toNarrowestNumber(final long l) {
return isRepresentableAsInt(l) ? Integer.valueOf((int) l) : Double.valueOf((double) l);
}
/**
* JavaScript compliant conversion of Boolean to number
@ -1726,21 +1735,6 @@ public enum JSType {
}
}
/**
* Returns the boxed version of a primitive class
* @param clazz the class
* @return the boxed type of clazz, or unchanged if not primitive
*/
public static Class<?> getBoxedClass(final Class<?> clazz) {
if (clazz == int.class) {
return Integer.class;
} else if (clazz == double.class) {
return Double.class;
}
assert !clazz.isPrimitive();
return clazz;
}
/**
* Create a method handle constant of the correct primitive type
* for a constant object

View File

@ -0,0 +1,44 @@
/*
* Copyright (c) 2016, 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-8147845: Varargs Array functions still leaking longs
*
* @test
* @run
*/
Assert.assertTrue([].push() === 0);
Assert.assertTrue([].unshift() === 0);
Assert.assertTrue(typeof [].push() === 'number');
Assert.assertTrue(typeof [].unshift() === 'number');
Assert.assertTrue([].push(1, 2, 3) === 3);
Assert.assertTrue([].unshift(1, 2, 3) === 3);
Assert.assertTrue(typeof [].push(1, 2, 3) === 'number');
Assert.assertTrue(typeof [].unshift(1, 2, 3) === 'number');
Assert.assertTrue([].push(1) === 1);
Assert.assertTrue([].unshift(1) === 1);
Assert.assertTrue(typeof [].push(1) === 'number');
Assert.assertTrue(typeof [].unshift(1) === 'number');