8061391: concat as a builtin optimistic form, had to remove NoTypedArrayData and replace it, as we throw away a lot of optimistic link opportunities with NoTypedArrayData not being Continuous
Reviewed-by: attila, hannesw
This commit is contained in:
parent
e170fafd7c
commit
5f5c28bf63
nashorn
bin
src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal
codegen/types
objects
NativeArray.javaNativeFloat32Array.javaNativeFloat64Array.javaNativeInt16Array.javaNativeInt32Array.javaNativeInt8Array.javaNativeObject.javaNativeUint16Array.javaNativeUint32Array.javaNativeUint8Array.javaNativeUint8ClampedArray.java
parser
runtime
test/script/basic
@ -69,7 +69,6 @@ ENABLE_ASSERTIONS_FLAGS="-ea -esa"
|
|||||||
|
|
||||||
if [ -z $JFR_FILENAME ]; then
|
if [ -z $JFR_FILENAME ]; then
|
||||||
JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
|
JFR_FILENAME="./nashorn_$(date|sed "s/ /_/g"|sed "s/:/_/g").jfr"
|
||||||
echo "Using default JFR filename: ${JFR_FILENAME}..."
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Flight recorder
|
# Flight recorder
|
||||||
|
@ -586,6 +586,7 @@ public abstract class Type implements Comparable<Type>, BytecodeOps, Serializabl
|
|||||||
public int getSlots() {
|
public int getSlots() {
|
||||||
return slots;
|
return slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the widest or most common of two types
|
* Returns the widest or most common of two types
|
||||||
*
|
*
|
||||||
@ -608,6 +609,18 @@ public abstract class Type implements Comparable<Type>, BytecodeOps, Serializabl
|
|||||||
return type0.weight() > type1.weight() ? type0 : type1;
|
return type0.weight() > type1.weight() ? type0 : type1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the widest or most common of two types, given as classes
|
||||||
|
*
|
||||||
|
* @param type0 type one
|
||||||
|
* @param type1 type two
|
||||||
|
*
|
||||||
|
* @return the widest type
|
||||||
|
*/
|
||||||
|
public static Class<?> widest(final Class<?> type0, final Class<?> type1) {
|
||||||
|
return widest(Type.typeFor(type0), Type.typeFor(type1)).getTypeClass();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
|
* When doing widening for return types of a function or a ternary operator, it is not valid to widen a boolean to
|
||||||
* anything other than object. Note that this wouldn't be necessary if {@code Type.widest} did not allow
|
* anything other than object. Note that this wouldn't be necessary if {@code Type.widest} did not allow
|
||||||
|
@ -92,9 +92,10 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
private static final Object CALL_CMP = new Object();
|
private static final Object CALL_CMP = new Object();
|
||||||
private static final Object TO_LOCALE_STRING = new Object();
|
private static final Object TO_LOCALE_STRING = new Object();
|
||||||
|
|
||||||
private SwitchPoint lengthMadeNotWritableSwitchPoint;
|
private SwitchPoint lengthMadeNotWritableSwitchPoint;
|
||||||
private PushLinkLogic pushLinkLogic;
|
private PushLinkLogic pushLinkLogic;
|
||||||
private PopLinkLogic popLinkLogic;
|
private PopLinkLogic popLinkLogic;
|
||||||
|
private ConcatLinkLogic concatLinkLogic;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Index for the modification SwitchPoint that triggers when length
|
* Index for the modification SwitchPoint that triggers when length
|
||||||
@ -130,7 +131,9 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
this(ArrayData.allocate(array.length));
|
this(ArrayData.allocate(array.length));
|
||||||
|
|
||||||
ArrayData arrayData = this.getArray();
|
ArrayData arrayData = this.getArray();
|
||||||
arrayData.ensure(array.length - 1);
|
if (array.length > 0) {
|
||||||
|
arrayData.ensure(array.length - 1);
|
||||||
|
}
|
||||||
|
|
||||||
for (int index = 0; index < array.length; index++) {
|
for (int index = 0; index < array.length; index++) {
|
||||||
final Object value = array[index];
|
final Object value = array[index];
|
||||||
@ -753,6 +756,79 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
return construct(newObj, self, new Object[]{length});
|
return construct(newObj, self, new Object[]{length});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
||||||
|
*
|
||||||
|
* @param self self reference
|
||||||
|
* @param arg argument
|
||||||
|
* @return resulting NativeArray
|
||||||
|
*/
|
||||||
|
@SpecializedFunction(linkLogic=ConcatLinkLogic.class)
|
||||||
|
public static NativeArray concat(final Object self, final int arg) {
|
||||||
|
final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Integer.class).copy(); //get at least an integer data copy of this data
|
||||||
|
newData.fastPush(arg); //add an integer to its end
|
||||||
|
return new NativeArray(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
||||||
|
*
|
||||||
|
* @param self self reference
|
||||||
|
* @param arg argument
|
||||||
|
* @return resulting NativeArray
|
||||||
|
*/
|
||||||
|
@SpecializedFunction(linkLogic=ConcatLinkLogic.class)
|
||||||
|
public static NativeArray concat(final Object self, final long arg) {
|
||||||
|
final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Long.class).copy(); //get at least a long array data copy of this data
|
||||||
|
newData.fastPush(arg); //add a long at the end
|
||||||
|
return new NativeArray(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
||||||
|
*
|
||||||
|
* @param self self reference
|
||||||
|
* @param arg argument
|
||||||
|
* @return resulting NativeArray
|
||||||
|
*/
|
||||||
|
@SpecializedFunction(linkLogic=ConcatLinkLogic.class)
|
||||||
|
public static NativeArray concat(final Object self, final double arg) {
|
||||||
|
final ContinuousArrayData newData = getContinuousArrayDataCCE(self, Double.class).copy(); //get at least a number array data copy of this data
|
||||||
|
newData.fastPush(arg); //add a double at the end
|
||||||
|
return new NativeArray(newData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
||||||
|
*
|
||||||
|
* @param self self reference
|
||||||
|
* @param arg argument
|
||||||
|
* @return resulting NativeArray
|
||||||
|
*/
|
||||||
|
@SpecializedFunction(linkLogic=ConcatLinkLogic.class)
|
||||||
|
public static NativeArray concat(final Object self, final Object arg) {
|
||||||
|
//arg is [NativeArray] of same type.
|
||||||
|
final ContinuousArrayData selfData = getContinuousArrayDataCCE(self);
|
||||||
|
final ContinuousArrayData newData;
|
||||||
|
|
||||||
|
if (arg instanceof NativeArray) {
|
||||||
|
final ContinuousArrayData argData = (ContinuousArrayData)((NativeArray)arg).getArray();
|
||||||
|
if (argData.isEmpty()) {
|
||||||
|
newData = selfData.copy();
|
||||||
|
} else if (selfData.isEmpty()) {
|
||||||
|
newData = argData.copy();
|
||||||
|
} else {
|
||||||
|
final Class<?> widestElementType = selfData.widest(argData).getBoxedElementType();
|
||||||
|
newData = ((ContinuousArrayData)selfData.convert(widestElementType)).fastConcat((ContinuousArrayData)argData.convert(widestElementType));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newData = getContinuousArrayDataCCE(self, Object.class).copy();
|
||||||
|
newData.fastPush(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NativeArray(newData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
* ECMA 15.4.4.4 Array.prototype.concat ( [ item1 [ , item2 [ , ... ] ] ] )
|
||||||
*
|
*
|
||||||
@ -763,6 +839,7 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
@Function(attributes = Attribute.NOT_ENUMERABLE, arity = 1)
|
||||||
public static NativeArray concat(final Object self, final Object... args) {
|
public static NativeArray concat(final Object self, final Object... args) {
|
||||||
final ArrayList<Object> list = new ArrayList<>();
|
final ArrayList<Object> list = new ArrayList<>();
|
||||||
|
|
||||||
concatToList(list, Global.toObject(self));
|
concatToList(list, Global.toObject(self));
|
||||||
|
|
||||||
for (final Object obj : args) {
|
for (final Object obj : args) {
|
||||||
@ -1692,13 +1769,15 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
return pushLinkLogic == null ? new PushLinkLogic(this) : pushLinkLogic;
|
return pushLinkLogic == null ? new PushLinkLogic(this) : pushLinkLogic;
|
||||||
} else if (clazz == PopLinkLogic.class) {
|
} else if (clazz == PopLinkLogic.class) {
|
||||||
return popLinkLogic == null ? new PopLinkLogic(this) : pushLinkLogic;
|
return popLinkLogic == null ? new PopLinkLogic(this) : pushLinkLogic;
|
||||||
|
} else if (clazz == ConcatLinkLogic.class) {
|
||||||
|
return concatLinkLogic == null ? new ConcatLinkLogic(this) : concatLinkLogic;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasPerInstanceAssumptions() {
|
public boolean hasPerInstanceAssumptions() {
|
||||||
return true; //length switchpoint
|
return true; //length writable switchpoint
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1797,6 +1876,40 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is linker logic for optimistic concatenations
|
||||||
|
*/
|
||||||
|
private static final class ConcatLinkLogic extends ArrayLinkLogic {
|
||||||
|
private ConcatLinkLogic(final NativeArray array) {
|
||||||
|
super(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean canLink(final Object self, final CallSiteDescriptor desc, final LinkRequest request) {
|
||||||
|
final Object[] args = request.getArguments();
|
||||||
|
|
||||||
|
if (args.length != 3) { //single argument check
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final ContinuousArrayData selfData = getContinuousArrayData(self);
|
||||||
|
if (selfData == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Object arg = args[2];
|
||||||
|
//args[2] continuousarray or non arraydata, let past non array datas
|
||||||
|
if (arg instanceof NativeArray) {
|
||||||
|
final ContinuousArrayData argData = getContinuousArrayData(arg);
|
||||||
|
if (argData == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is linker logic for optimistic pushes
|
* This is linker logic for optimistic pushes
|
||||||
*/
|
*/
|
||||||
@ -1864,6 +1977,14 @@ public final class NativeArray extends ScriptObject implements OptimisticBuiltin
|
|||||||
throw new ClassCastException();
|
throw new ClassCastException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self) {
|
||||||
|
try {
|
||||||
|
return (ContinuousArrayData)((NativeArray)self).getArray();
|
||||||
|
} catch (final NullPointerException e) {
|
||||||
|
throw new ClassCastException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self, final Class<?> elementType) {
|
private static final ContinuousArrayData getContinuousArrayDataCCE(final Object self, final Class<?> elementType) {
|
||||||
try {
|
try {
|
||||||
return (ContinuousArrayData)((NativeArray)self).getArray(elementType); //ensure element type can fit "elementType"
|
return (ContinuousArrayData)((NativeArray)self).getArray(elementType); //ensure element type can fit "elementType"
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat32Array.java
@ -89,6 +89,11 @@ public final class NativeFloat32Array extends ArrayBufferView {
|
|||||||
return double.class;
|
return double.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Double.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MethodHandle getGetElem() {
|
protected MethodHandle getGetElem() {
|
||||||
return GET_ELEM;
|
return GET_ELEM;
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeFloat64Array.java
@ -99,6 +99,11 @@ public final class NativeFloat64Array extends ArrayBufferView {
|
|||||||
return double.class;
|
return double.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Double.class;
|
||||||
|
}
|
||||||
|
|
||||||
private double getElem(final int index) {
|
private double getElem(final int index) {
|
||||||
try {
|
try {
|
||||||
return nb.get(index);
|
return nb.get(index);
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt16Array.java
@ -100,6 +100,11 @@ public final class NativeInt16Array extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
private int getElem(final int index) {
|
private int getElem(final int index) {
|
||||||
try {
|
try {
|
||||||
return nb.get(index);
|
return nb.get(index);
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeInt32Array.java
@ -117,6 +117,11 @@ public final class NativeInt32Array extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(final int index) {
|
public int getInt(final int index) {
|
||||||
return getElem(index);
|
return getElem(index);
|
||||||
|
@ -98,6 +98,11 @@ public final class NativeInt8Array extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
private int getElem(final int index) {
|
private int getElem(final int index) {
|
||||||
try {
|
try {
|
||||||
return nb.get(index);
|
return nb.get(index);
|
||||||
|
@ -28,7 +28,6 @@ package jdk.nashorn.internal.objects;
|
|||||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint16Array.java
@ -123,6 +123,11 @@ public final class NativeUint16Array extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(final int index) {
|
public int getInt(final int index) {
|
||||||
return getElem(index);
|
return getElem(index);
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint32Array.java
@ -132,6 +132,11 @@ public final class NativeUint32Array extends ArrayBufferView {
|
|||||||
return long.class;
|
return long.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(final int index) {
|
public int getInt(final int index) {
|
||||||
return (int)getLong(index);
|
return (int)getLong(index);
|
||||||
|
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
5
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/objects/NativeUint8Array.java
@ -123,6 +123,11 @@ public final class NativeUint8Array extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getInt(final int index) {
|
public int getInt(final int index) {
|
||||||
return getElem(index);
|
return getElem(index);
|
||||||
|
@ -103,6 +103,11 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
|
|||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return int.class;
|
||||||
|
}
|
||||||
|
|
||||||
private int getElem(final int index) {
|
private int getElem(final int index) {
|
||||||
try {
|
try {
|
||||||
return nb.get(index) & 0xff;
|
return nb.get(index) & 0xff;
|
||||||
|
@ -32,7 +32,6 @@ import static jdk.nashorn.internal.parser.TokenType.ESCSTRING;
|
|||||||
import static jdk.nashorn.internal.parser.TokenType.RBRACE;
|
import static jdk.nashorn.internal.parser.TokenType.RBRACE;
|
||||||
import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
|
import static jdk.nashorn.internal.parser.TokenType.RBRACKET;
|
||||||
import static jdk.nashorn.internal.parser.TokenType.STRING;
|
import static jdk.nashorn.internal.parser.TokenType.STRING;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import jdk.nashorn.internal.ir.Expression;
|
import jdk.nashorn.internal.ir.Expression;
|
||||||
|
@ -29,7 +29,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
|
|||||||
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
|
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY;
|
||||||
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
import static jdk.nashorn.internal.lookup.Lookup.MH;
|
||||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Array;
|
import java.lang.reflect.Array;
|
||||||
@ -1775,6 +1774,23 @@ 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 == long.class) {
|
||||||
|
return Long.class;
|
||||||
|
} else if (clazz == double.class) {
|
||||||
|
return Double.class;
|
||||||
|
}
|
||||||
|
assert !clazz.isPrimitive();
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a method handle constant of the correct primitive type
|
* Create a method handle constant of the correct primitive type
|
||||||
* for a constant object
|
* for a constant object
|
||||||
|
@ -692,8 +692,7 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
assert isValidArrayIndex(index) : "invalid array index";
|
assert isValidArrayIndex(index) : "invalid array index";
|
||||||
final long longIndex = ArrayIndex.toLongIndex(index);
|
final long longIndex = ArrayIndex.toLongIndex(index);
|
||||||
doesNotHaveEnsureDelete(longIndex, getArray().length(), false);
|
doesNotHaveEnsureDelete(longIndex, getArray().length(), false);
|
||||||
setArray(getArray().ensure(longIndex));
|
setArray(getArray().ensure(longIndex).set(index,value, false));
|
||||||
setArray(getArray().set(index, value, false));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkIntegerKey(final String key) {
|
private void checkIntegerKey(final String key) {
|
||||||
@ -1462,9 +1461,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
|
|
||||||
//invalidate any fast array setters
|
//invalidate any fast array setters
|
||||||
final ArrayData array = getArray();
|
final ArrayData array = getArray();
|
||||||
if (array != null) {
|
assert array != null;
|
||||||
array.invalidateSetters();
|
setArray(ArrayData.preventExtension(array));
|
||||||
}
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2645,20 +2643,22 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
* @param newLength new length to set
|
* @param newLength new length to set
|
||||||
*/
|
*/
|
||||||
public final void setLength(final long newLength) {
|
public final void setLength(final long newLength) {
|
||||||
final long arrayLength = getArray().length();
|
ArrayData data = getArray();
|
||||||
if (newLength == arrayLength) {
|
final long arrayLength = data.length();
|
||||||
return;
|
if (newLength == arrayLength) {
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newLength > arrayLength) {
|
if (newLength > arrayLength) {
|
||||||
setArray(getArray().ensure(newLength - 1));
|
data = data.ensure(newLength - 1);
|
||||||
if (getArray().canDelete(arrayLength, newLength - 1, false)) {
|
if (data.canDelete(arrayLength, newLength - 1, false)) {
|
||||||
setArray(getArray().delete(arrayLength, newLength - 1));
|
data = data.delete(arrayLength, newLength - 1);
|
||||||
}
|
}
|
||||||
return;
|
setArray(data);
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (newLength < arrayLength) {
|
if (newLength < arrayLength) {
|
||||||
long actualLength = newLength;
|
long actualLength = newLength;
|
||||||
|
|
||||||
// Check for numeric keys in property map and delete them or adjust length, depending on whether
|
// Check for numeric keys in property map and delete them or adjust length, depending on whether
|
||||||
@ -2680,8 +2680,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setArray(getArray().shrink(actualLength));
|
setArray(data.shrink(actualLength));
|
||||||
getArray().setLength(actualLength);
|
data.setLength(actualLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3194,8 +3194,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(primitiveKey);
|
final int index = getArrayIndex(primitiveKey);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3213,8 +3214,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(primitiveKey);
|
final int index = getArrayIndex(primitiveKey);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3232,8 +3234,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(primitiveKey);
|
final int index = getArrayIndex(primitiveKey);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3251,8 +3254,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(primitiveKey);
|
final int index = getArrayIndex(primitiveKey);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3269,8 +3273,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3287,8 +3292,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3305,8 +3311,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3323,8 +3330,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3341,8 +3349,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3359,8 +3368,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3377,8 +3387,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3395,8 +3406,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3413,7 +3425,8 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
if (getArray().has(index)) {
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
final ArrayData data = getArray();
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3429,8 +3442,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3447,8 +3461,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
@ -3465,8 +3480,9 @@ public abstract class ScriptObject implements PropertyAccess {
|
|||||||
final int index = getArrayIndex(key);
|
final int index = getArrayIndex(key);
|
||||||
|
|
||||||
if (isValidArrayIndex(index)) {
|
if (isValidArrayIndex(index)) {
|
||||||
if (getArray().has(index)) {
|
final ArrayData data = getArray();
|
||||||
setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
if (data.has(index)) {
|
||||||
|
setArray(data.set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
|
||||||
} else {
|
} else {
|
||||||
doesNotHave(index, value, callSiteFlags);
|
doesNotHave(index, value, callSiteFlags);
|
||||||
}
|
}
|
||||||
|
38
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/AnyElements.java
Normal file
38
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/AnyElements.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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. Oracle designates this
|
||||||
|
* particular file as subject to the "Classpath" exception as provided
|
||||||
|
* by Oracle in the LICENSE file that accompanied this code.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker interface for any ContinuousArray with any elements
|
||||||
|
* Used for type checks that throw ClassCastExceptions and force relinks
|
||||||
|
* for fast NativeArray specializations of builtin methods
|
||||||
|
*/
|
||||||
|
public interface AnyElements {
|
||||||
|
/**
|
||||||
|
* Return a numeric weight of the element type - wider is higher
|
||||||
|
* @return element type weight
|
||||||
|
*/
|
||||||
|
public int getElementWeight();
|
||||||
|
}
|
228
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java
228
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/ArrayData.java
@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Array;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||||
@ -37,6 +38,7 @@ import jdk.nashorn.internal.codegen.types.Type;
|
|||||||
import jdk.nashorn.internal.objects.Global;
|
import jdk.nashorn.internal.objects.Global;
|
||||||
import jdk.nashorn.internal.runtime.JSType;
|
import jdk.nashorn.internal.runtime.JSType;
|
||||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
|
import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -49,10 +51,180 @@ public abstract class ArrayData {
|
|||||||
/** Mask for getting a chunk */
|
/** Mask for getting a chunk */
|
||||||
protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
|
protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
|
||||||
|
|
||||||
|
/** Untouched data - still link callsites as IntArrayData, but expands to
|
||||||
|
* a proper ArrayData when we try to write to it */
|
||||||
|
public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable empty array to get ScriptObjects started.
|
* Immutable empty array to get ScriptObjects started.
|
||||||
|
* Use the same array and convert it to mutable as soon as it is modified
|
||||||
*/
|
*/
|
||||||
public static final ArrayData EMPTY_ARRAY = new NoTypeArrayData();
|
private static class UntouchedArrayData extends ContinuousArrayData {
|
||||||
|
private UntouchedArrayData() {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private UntouchedArrayData(final int length) {
|
||||||
|
super(length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayData toRealArrayData() {
|
||||||
|
return toRealArrayData(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayData toRealArrayData(final int index) {
|
||||||
|
final IntArrayData newData = new IntArrayData(index + 1);
|
||||||
|
if (index == 0) {
|
||||||
|
return newData;
|
||||||
|
}
|
||||||
|
return new DeletedRangeArrayFilter(newData, 0, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData copy() {
|
||||||
|
return new UntouchedArrayData((int)length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object asArrayOfType(final Class<?> componentType) {
|
||||||
|
return Array.newInstance(componentType, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object[] asObjectArray() {
|
||||||
|
return ScriptRuntime.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData ensure(final long safeIndex) {
|
||||||
|
if (safeIndex > 0L) {
|
||||||
|
return toRealArrayData((int)safeIndex).ensure(safeIndex);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData convert(final Class<?> type) {
|
||||||
|
return toRealArrayData(0).convert(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void shiftLeft(final int by) {
|
||||||
|
//nop, always empty or we wouldn't be of this class
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData shiftRight(final int by) {
|
||||||
|
return this; //always empty or we wouldn't be of this class
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData shrink(final long newLength) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
|
return toRealArrayData(index).set(index, value, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
|
return toRealArrayData(index).set(index, value, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
|
return toRealArrayData(index).set(index, value, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
|
return toRealArrayData(index).set(index, value, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(final int index) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(index); //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(final int index) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(index); //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(final int index) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(index); //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getObject(final int index) {
|
||||||
|
throw new ArrayIndexOutOfBoundsException(index); //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean has(final int index) {
|
||||||
|
return false; //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final int index) {
|
||||||
|
return new DeletedRangeArrayFilter(this, index, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData delete(final long fromIndex, final long toIndex) {
|
||||||
|
return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object pop() {
|
||||||
|
return ScriptRuntime.UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData push(final boolean strict, final Object item) {
|
||||||
|
return toRealArrayData().push(strict, item);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData slice(final long from, final long to) {
|
||||||
|
return this; //empty
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
return otherData.copy();
|
||||||
|
}
|
||||||
|
|
||||||
|
//no need to override fastPopInt, as the default behavior is to throw classcast exception so we
|
||||||
|
//can relink and return an undefined, this is the IntArrayData default behavior
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return getClass().getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodHandle getElementSetter(final Class<?> elementType) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getElementType() {
|
||||||
|
return int.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Length of the array data. Not necessarily length of the wrapped array.
|
* Length of the array data. Not necessarily length of the wrapped array.
|
||||||
@ -77,7 +249,7 @@ public abstract class ArrayData {
|
|||||||
* Factory method for unspecified array - start as int
|
* Factory method for unspecified array - start as int
|
||||||
* @return ArrayData
|
* @return ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData initialArray() {
|
public final static ArrayData initialArray() {
|
||||||
return new IntArrayData();
|
return new IntArrayData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,33 +264,22 @@ public abstract class ArrayData {
|
|||||||
throw new UnwarrantedOptimismException(data.getObject(index), programPoint);
|
throw new UnwarrantedOptimismException(data.getObject(index), programPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int alignUp(final int size) {
|
/**
|
||||||
|
* Align an array size up to the nearest array chunk size
|
||||||
|
* @param size size required
|
||||||
|
* @return size given, always >= size
|
||||||
|
*/
|
||||||
|
protected final static int alignUp(final int size) {
|
||||||
return size + CHUNK_SIZE - 1 & ~(CHUNK_SIZE - 1);
|
return size + CHUNK_SIZE - 1 & ~(CHUNK_SIZE - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic invalidation hook for script object to have call sites to this array indexing
|
|
||||||
* relinked, e.g. when a native array is marked as non extensible
|
|
||||||
*/
|
|
||||||
public void invalidateGetters() {
|
|
||||||
//subclass responsibility
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generic invalidation hook for script object to have call sites to this array indexing
|
|
||||||
* relinked, e.g. when a native array is marked as non extensible
|
|
||||||
*/
|
|
||||||
public void invalidateSetters() {
|
|
||||||
//subclass responsibility
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method for unspecified array with given length - start as int array data
|
* Factory method for unspecified array with given length - start as int array data
|
||||||
*
|
*
|
||||||
* @param length the initial length
|
* @param length the initial length
|
||||||
* @return ArrayData
|
* @return ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final int length) {
|
public static final ArrayData allocate(final int length) {
|
||||||
if (length == 0) {
|
if (length == 0) {
|
||||||
return new IntArrayData();
|
return new IntArrayData();
|
||||||
} else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
|
} else if (length >= SparseArrayData.MAX_DENSE_LENGTH) {
|
||||||
@ -134,7 +295,7 @@ public abstract class ArrayData {
|
|||||||
* @param array the array
|
* @param array the array
|
||||||
* @return ArrayData wrapping this array
|
* @return ArrayData wrapping this array
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final Object array) {
|
public static final ArrayData allocate(final Object array) {
|
||||||
final Class<?> clazz = array.getClass();
|
final Class<?> clazz = array.getClass();
|
||||||
|
|
||||||
if (clazz == int[].class) {
|
if (clazz == int[].class) {
|
||||||
@ -154,7 +315,7 @@ public abstract class ArrayData {
|
|||||||
* @param array the array to use for initial elements
|
* @param array the array to use for initial elements
|
||||||
* @return the ArrayData
|
* @return the ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final int[] array) {
|
public static final ArrayData allocate(final int[] array) {
|
||||||
return new IntArrayData(array, array.length);
|
return new IntArrayData(array, array.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,7 +325,7 @@ public abstract class ArrayData {
|
|||||||
* @param array the array to use for initial elements
|
* @param array the array to use for initial elements
|
||||||
* @return the ArrayData
|
* @return the ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final long[] array) {
|
public static final ArrayData allocate(final long[] array) {
|
||||||
return new LongArrayData(array, array.length);
|
return new LongArrayData(array, array.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +335,7 @@ public abstract class ArrayData {
|
|||||||
* @param array the array to use for initial elements
|
* @param array the array to use for initial elements
|
||||||
* @return the ArrayData
|
* @return the ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final double[] array) {
|
public static final ArrayData allocate(final double[] array) {
|
||||||
return new NumberArrayData(array, array.length);
|
return new NumberArrayData(array, array.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -184,7 +345,7 @@ public abstract class ArrayData {
|
|||||||
* @param array the array to use for initial elements
|
* @param array the array to use for initial elements
|
||||||
* @return the ArrayData
|
* @return the ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final Object[] array) {
|
public static final ArrayData allocate(final Object[] array) {
|
||||||
return new ObjectArrayData(array, array.length);
|
return new ObjectArrayData(array, array.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +355,7 @@ public abstract class ArrayData {
|
|||||||
* @param buf the nio ByteBuffer to wrap
|
* @param buf the nio ByteBuffer to wrap
|
||||||
* @return the ArrayData
|
* @return the ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData allocate(final ByteBuffer buf) {
|
public static final ArrayData allocate(final ByteBuffer buf) {
|
||||||
return new ByteBufferArrayData(buf);
|
return new ByteBufferArrayData(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +365,7 @@ public abstract class ArrayData {
|
|||||||
* @param underlying the underlying ArrayData to wrap in the freeze filter
|
* @param underlying the underlying ArrayData to wrap in the freeze filter
|
||||||
* @return the frozen ArrayData
|
* @return the frozen ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData freeze(final ArrayData underlying) {
|
public static final ArrayData freeze(final ArrayData underlying) {
|
||||||
return new FrozenArrayFilter(underlying);
|
return new FrozenArrayFilter(underlying);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,10 +375,20 @@ public abstract class ArrayData {
|
|||||||
* @param underlying the underlying ArrayData to wrap in the seal filter
|
* @param underlying the underlying ArrayData to wrap in the seal filter
|
||||||
* @return the sealed ArrayData
|
* @return the sealed ArrayData
|
||||||
*/
|
*/
|
||||||
public static ArrayData seal(final ArrayData underlying) {
|
public static final ArrayData seal(final ArrayData underlying) {
|
||||||
return new SealedArrayFilter(underlying);
|
return new SealedArrayFilter(underlying);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prevent this array from being extended
|
||||||
|
*
|
||||||
|
* @param underlying the underlying ArrayData to wrap in the non extensible filter
|
||||||
|
* @return new array data, filtered
|
||||||
|
*/
|
||||||
|
public static final ArrayData preventExtension(final ArrayData underlying) {
|
||||||
|
return new NonExtensibleArrayFilter(underlying);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the length of the array data. This may differ from the actual
|
* Return the length of the array data. This may differ from the actual
|
||||||
* length of the array this wraps as length may be set or gotten as any
|
* length of the array this wraps as length may be set or gotten as any
|
||||||
@ -728,5 +899,4 @@ public abstract class ArrayData {
|
|||||||
public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
|
public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
|
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -30,7 +29,6 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
|
|||||||
import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
|
import static jdk.nashorn.internal.runtime.JSType.getAccessorTypeIndex;
|
||||||
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
|
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT;
|
||||||
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
|
import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.isValid;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
@ -50,9 +48,6 @@ import jdk.nashorn.internal.runtime.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
@Logger(name="arrays")
|
@Logger(name="arrays")
|
||||||
public abstract class ContinuousArrayData extends ArrayData {
|
public abstract class ContinuousArrayData extends ArrayData {
|
||||||
|
|
||||||
private SwitchPoint sp;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* @param length length (elementLength)
|
* @param length length (elementLength)
|
||||||
@ -61,18 +56,6 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
super(length);
|
super(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SwitchPoint ensureSwitchPointExists() {
|
|
||||||
if (sp == null){
|
|
||||||
sp = new SwitchPoint();
|
|
||||||
}
|
|
||||||
return sp;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void invalidateSetters() {
|
|
||||||
SwitchPoint.invalidateAll(new SwitchPoint[] { ensureSwitchPointExists() });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if we can put one more element at the end of this continous
|
* Check if we can put one more element at the end of this continous
|
||||||
* array without reallocating, or if we are overwriting an already
|
* array without reallocating, or if we are overwriting an already
|
||||||
@ -85,6 +68,14 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
return has(index) || (index == length && ensure(index) == this);
|
return has(index) || (index == length && ensure(index) == this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if an arraydata is empty
|
||||||
|
* @return true if empty
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
return length == 0L;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return element getter for a certain type at a certain program point
|
* Return element getter for a certain type at a certain program point
|
||||||
* @param returnType return type
|
* @param returnType return type
|
||||||
@ -109,13 +100,16 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
* @param index index to check - currently only int indexes
|
* @param index index to check - currently only int indexes
|
||||||
* @return index
|
* @return index
|
||||||
*/
|
*/
|
||||||
protected int throwHas(final int index) {
|
protected final int throwHas(final int index) {
|
||||||
if (!has(index)) {
|
if (!has(index)) {
|
||||||
throw new ClassCastException();
|
throw new ClassCastException();
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public abstract ContinuousArrayData copy();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the type used to store an element in this array
|
* Returns the type used to store an element in this array
|
||||||
* @return element type
|
* @return element type
|
||||||
@ -127,6 +121,25 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
return Type.typeFor(getElementType());
|
return Type.typeFor(getElementType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the boxed type of the type used to store an element in this array
|
||||||
|
* @return element type
|
||||||
|
*/
|
||||||
|
public abstract Class<?> getBoxedElementType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the widest element type of two arrays. This can be done faster in subclasses, but
|
||||||
|
* this works for all ContinuousArrayDatas and for where more optimal checks haven't been
|
||||||
|
* implemented.
|
||||||
|
*
|
||||||
|
* @param otherData another ContinuousArrayData
|
||||||
|
* @return the widest boxed element type
|
||||||
|
*/
|
||||||
|
public ContinuousArrayData widest(final ContinuousArrayData otherData) {
|
||||||
|
final Class<?> elementType = getElementType();
|
||||||
|
return Type.widest(elementType, otherData.getElementType()) == elementType ? this : otherData;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a continuous array element getter
|
* Look up a continuous array element getter
|
||||||
* @param get getter, sometimes combined with a has check that throws CCE on failure for relink
|
* @param get getter, sometimes combined with a has check that throws CCE on failure for relink
|
||||||
@ -256,12 +269,7 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
final Object[] args = request.getArguments();
|
final Object[] args = request.getArguments();
|
||||||
final int index = (int)args[args.length - 2];
|
final int index = (int)args[args.length - 2];
|
||||||
|
|
||||||
//sp may be invalidated by e.g. preventExtensions before the first setter is linked
|
if (hasRoomFor(index)) {
|
||||||
//then it is already created. otherwise, create it here to guard against future
|
|
||||||
//invalidations
|
|
||||||
ensureSwitchPointExists();
|
|
||||||
|
|
||||||
if (!sp.hasBeenInvalidated() && hasRoomFor(index)) {
|
|
||||||
MethodHandle setElement = getElementSetter(elementType); //Z(continuousarraydata, int, int), return true if successful
|
MethodHandle setElement = getElementSetter(elementType); //Z(continuousarraydata, int, int), return true if successful
|
||||||
if (setElement != null) {
|
if (setElement != null) {
|
||||||
//else we are dealing with a wider type than supported by this callsite
|
//else we are dealing with a wider type than supported by this callsite
|
||||||
@ -269,7 +277,7 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
getArray = MH.asType(getArray, getArray.type().changeReturnType(getClass()));
|
getArray = MH.asType(getArray, getArray.type().changeReturnType(getClass()));
|
||||||
setElement = MH.filterArguments(setElement, 0, getArray);
|
setElement = MH.filterArguments(setElement, 0, getArray);
|
||||||
final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
|
final MethodHandle guard = MH.insertArguments(FAST_ACCESS_GUARD, 0, clazz);
|
||||||
return new GuardedInvocation(setElement, guard, sp, ClassCastException.class); //CCE if not a scriptObject anymore
|
return new GuardedInvocation(setElement, guard, (SwitchPoint)null, ClassCastException.class); //CCE if not a scriptObject anymore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,4 +352,13 @@ public abstract class ContinuousArrayData extends ArrayData {
|
|||||||
public Object fastPopObject() {
|
public Object fastPopObject() {
|
||||||
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
|
throw new ClassCastException(String.valueOf(getClass())); //type is wrong, relink
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specialization - fast concat implementation
|
||||||
|
* @param otherData data to concat
|
||||||
|
* @return new arraydata
|
||||||
|
*/
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
throw new ClassCastException(String.valueOf(getClass()) + " != " + String.valueOf(otherData.getClass()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
package jdk.nashorn.internal.runtime.arrays;
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
import static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
|
||||||
|
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -57,17 +56,32 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
* @param array an int array
|
* @param array an int array
|
||||||
* @param length a length, not necessarily array.length
|
* @param length a length, not necessarily array.length
|
||||||
*/
|
*/
|
||||||
IntArrayData(final int array[], final int length) {
|
IntArrayData(final int[] array, final int length) {
|
||||||
super(length);
|
super(length);
|
||||||
assert array.length >= length;
|
assert array == null || array.length >= length;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getElementType() {
|
public final Class<?> getElementType() {
|
||||||
return int.class;
|
return int.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Class<?> getBoxedElementType() {
|
||||||
|
return Integer.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getElementWeight() {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
|
||||||
|
return otherData;
|
||||||
|
}
|
||||||
|
|
||||||
private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "getElem", int.class, int.class).methodHandle();
|
private static final MethodHandle HAS_GET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "getElem", int.class, int.class).methodHandle();
|
||||||
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
|
private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), IntArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
|
||||||
|
|
||||||
@ -104,7 +118,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public IntArrayData copy() {
|
||||||
return new IntArrayData(array.clone(), (int)length);
|
return new IntArrayData(array.clone(), (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,8 +179,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
public ArrayData convert(final Class<?> type) {
|
public ArrayData convert(final Class<?> type) {
|
||||||
if (type == Integer.class) {
|
if (type == Integer.class) {
|
||||||
return this;
|
return this;
|
||||||
}
|
} else if (type == Long.class) {
|
||||||
if (type == Long.class) {
|
|
||||||
return convertToLong();
|
return convertToLong();
|
||||||
} else if (type == Double.class) {
|
} else if (type == Double.class) {
|
||||||
return convertToDouble();
|
return convertToDouble();
|
||||||
@ -209,8 +222,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
Arrays.fill(array, (int) newLength, array.length, 0);
|
Arrays.fill(array, (int)newLength, array.length, 0);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,10 +334,7 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData slice(final long from, final long to) {
|
public ArrayData slice(final long from, final long to) {
|
||||||
final long start = from < 0 ? from + length : from;
|
return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)(to - (from < 0 ? from + length : from)));
|
||||||
final long newLength = to - start;
|
|
||||||
|
|
||||||
return new IntArrayData(Arrays.copyOfRange(array, (int)from, (int)to), (int)newLength);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -347,7 +356,13 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
final ArrayData returnValue = removed == 0 ?
|
final ArrayData returnValue = removed == 0 ?
|
||||||
EMPTY_ARRAY : new IntArrayData(Arrays.copyOfRange(array, start, start + removed), removed);
|
EMPTY_ARRAY :
|
||||||
|
new IntArrayData(
|
||||||
|
Arrays.copyOfRange(
|
||||||
|
array,
|
||||||
|
start,
|
||||||
|
start + removed),
|
||||||
|
removed);
|
||||||
|
|
||||||
if (newLength != oldLength) {
|
if (newLength != oldLength) {
|
||||||
final int[] newArray;
|
final int[] newArray;
|
||||||
@ -403,4 +418,26 @@ final class IntArrayData extends ContinuousArrayData implements IntElements {
|
|||||||
public Object fastPopObject() {
|
public Object fastPopObject() {
|
||||||
return fastPopInt();
|
return fastPopInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
final int otherLength = (int)otherData.length;
|
||||||
|
final int thisLength = (int)length;
|
||||||
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
|
final int[] otherArray = ((IntArrayData)otherData).array;
|
||||||
|
final int newLength = otherLength + thisLength;
|
||||||
|
final int[] newArray = new int[ArrayData.alignUp(newLength)];
|
||||||
|
|
||||||
|
System.arraycopy(array, 0, newArray, 0, thisLength);
|
||||||
|
System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
|
||||||
|
|
||||||
|
return new IntArrayData(newArray, newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
assert length <= array.length : length + " > " + array.length;
|
||||||
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,16 +52,31 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
LongArrayData(final long array[], final int length) {
|
LongArrayData(final long array[], final int length) {
|
||||||
super(length);
|
super(length);
|
||||||
assert array.length >= length;
|
assert array.length >= length;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getElementType() {
|
public final Class<?> getElementType() {
|
||||||
return long.class;
|
return long.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public final Class<?> getBoxedElementType() {
|
||||||
|
return Long.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
|
||||||
|
return otherData instanceof IntElements ? this : otherData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getElementWeight() {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LongArrayData copy() {
|
||||||
return new LongArrayData(array.clone(), (int)length);
|
return new LongArrayData(array.clone(), (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,7 +116,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData convert(final Class<?> type) {
|
public ContinuousArrayData convert(final Class<?> type) {
|
||||||
if (type == Integer.class || type == Long.class) {
|
if (type == Integer.class || type == Long.class) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@ -145,8 +160,7 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
Arrays.fill(array, (int) newLength, array.length, 0);
|
Arrays.fill(array, (int)newLength, array.length, 0L);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,4 +373,37 @@ final class LongArrayData extends ContinuousArrayData implements IntOrLongElemen
|
|||||||
public Object fastPopObject() {
|
public Object fastPopObject() {
|
||||||
return fastPopLong();
|
return fastPopLong();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
final int otherLength = (int)otherData.length;
|
||||||
|
final int thisLength = (int)length;
|
||||||
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
|
final long[] otherArray = ((LongArrayData)otherData).array;
|
||||||
|
final int newLength = otherLength + thisLength;
|
||||||
|
final long[] newArray = new long[ArrayData.alignUp(newLength)];
|
||||||
|
|
||||||
|
System.arraycopy(array, 0, newArray, 0, thisLength);
|
||||||
|
System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
|
||||||
|
|
||||||
|
return new LongArrayData(newArray, newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
assert length <= array.length : length + " > " + array.length;
|
||||||
|
|
||||||
|
final StringBuilder sb = new StringBuilder(getClass().getSimpleName()).
|
||||||
|
append(": [");
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
sb.append(array[i]).append('L'); //make sure L suffix is on elements, to discriminate this from IntArrayData.toString()
|
||||||
|
if (i + 1 < length) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append(']');
|
||||||
|
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,186 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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. Oracle designates this
|
|
||||||
* particular file as subject to the "Classpath" exception as provided
|
|
||||||
* by Oracle in the LICENSE file that accompanied this code.
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package jdk.nashorn.internal.runtime.arrays;
|
|
||||||
|
|
||||||
import java.lang.reflect.Array;
|
|
||||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Place holding array data for non-array objects. Activates a true array when
|
|
||||||
* accessed. Should only exist as a singleton defined in ArrayData.
|
|
||||||
*/
|
|
||||||
final class NoTypeArrayData extends ArrayData {
|
|
||||||
NoTypeArrayData() {
|
|
||||||
super(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
NoTypeArrayData(final long length) {
|
|
||||||
super(length);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object[] asObjectArray() {
|
|
||||||
return ScriptRuntime.EMPTY_ARRAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData copy() {
|
|
||||||
return new NoTypeArrayData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object asArrayOfType(final Class<?> componentType) {
|
|
||||||
return Array.newInstance(componentType, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData convert(final Class<?> type) {
|
|
||||||
final long len = length;
|
|
||||||
final ArrayData arrayData;
|
|
||||||
if (type == Long.class) {
|
|
||||||
arrayData = new LongArrayData(new long[ArrayData.nextSize((int)len)], (int)len);
|
|
||||||
} else if (type == Double.class) {
|
|
||||||
arrayData = new NumberArrayData(new double[ArrayData.nextSize((int)len)], (int)len);
|
|
||||||
} else if (type == Integer.class) {
|
|
||||||
arrayData = new IntArrayData(new int[ArrayData.nextSize((int)len)], (int)len);
|
|
||||||
} else {
|
|
||||||
assert !type.isPrimitive();
|
|
||||||
arrayData = new ObjectArrayData(new Object[ArrayData.nextSize((int)len)], (int)len);
|
|
||||||
}
|
|
||||||
return length == 0 ? arrayData : new DeletedRangeArrayFilter(arrayData, 0, len - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void shiftLeft(final int by) {
|
|
||||||
//empty
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData shiftRight(final int by) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData ensure(final long safeIndex) {
|
|
||||||
if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
|
|
||||||
return new SparseArrayData(this, safeIndex + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't trample the shared EMPTY_ARRAY.
|
|
||||||
if (length == 0) {
|
|
||||||
return new NoTypeArrayData(Math.max(safeIndex + 1, length));
|
|
||||||
}
|
|
||||||
|
|
||||||
setLength(Math.max(safeIndex + 1, length));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData shrink(final long newLength) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData set(final int index, final Object value, final boolean strict) {
|
|
||||||
ArrayData newData;
|
|
||||||
|
|
||||||
if (value instanceof Double) {
|
|
||||||
newData = convert(Double.class);
|
|
||||||
} else if (value instanceof Long) {
|
|
||||||
newData = convert(Long.class);
|
|
||||||
} else if (value instanceof Integer) {
|
|
||||||
newData = convert(Integer.class);
|
|
||||||
} else {
|
|
||||||
assert !(value instanceof Number);
|
|
||||||
newData = convert(value == null ? Object.class : value.getClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
return newData.set(index, value, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData set(final int index, final int value, final boolean strict) {
|
|
||||||
final ArrayData newData = convert(Integer.class);
|
|
||||||
return newData.set(index, value, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData set(final int index, final long value, final boolean strict) {
|
|
||||||
final ArrayData newData = convert(Long.class);
|
|
||||||
return newData.set(index, value, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData set(final int index, final double value, final boolean strict) {
|
|
||||||
final ArrayData newData = convert(Double.class);
|
|
||||||
return newData.set(index, value, strict);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getInt(final int index) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getLong(final int index) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double getDouble(final int index) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getObject(final int index) {
|
|
||||||
throw new ArrayIndexOutOfBoundsException(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean has(final int index) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData delete(final int index) {
|
|
||||||
return new DeletedRangeArrayFilter(this, index, index);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData delete(final long fromIndex, final long toIndex) {
|
|
||||||
return new DeletedRangeArrayFilter(this, fromIndex, toIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object pop() {
|
|
||||||
return ScriptRuntime.UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ArrayData slice(final long from, final long to) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
68
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NonExtensibleArrayFilter.java
Normal file
68
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/arrays/NonExtensibleArrayFilter.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package jdk.nashorn.internal.runtime.arrays;
|
||||||
|
|
||||||
|
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||||
|
import jdk.nashorn.internal.objects.Global;
|
||||||
|
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter class that wrap arrays that have been tagged non extensible
|
||||||
|
*/
|
||||||
|
public class NonExtensibleArrayFilter extends ArrayFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
* @param underlying array
|
||||||
|
*/
|
||||||
|
public NonExtensibleArrayFilter(final ArrayData underlying) {
|
||||||
|
super(underlying);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData copy() {
|
||||||
|
return new NonExtensibleArrayFilter(underlying.copy());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData slice(final long from, final long to) {
|
||||||
|
return new NonExtensibleArrayFilter(underlying.slice(from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ArrayData extensionCheck(final boolean strict, final int index) {
|
||||||
|
if (!strict) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
throw typeError(Global.instance(), "object.non.extensible", String.valueOf(index), ScriptRuntime.safeToString(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||||
|
if (has(index)) {
|
||||||
|
return underlying.set(index, value, strict);
|
||||||
|
}
|
||||||
|
return extensionCheck(strict, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final int value, final boolean strict) {
|
||||||
|
if (has(index)) {
|
||||||
|
return underlying.set(index, value, strict);
|
||||||
|
}
|
||||||
|
return extensionCheck(strict, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final long value, final boolean strict) {
|
||||||
|
if (has(index)) {
|
||||||
|
return underlying.set(index, value, strict);
|
||||||
|
}
|
||||||
|
return extensionCheck(strict, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ArrayData set(final int index, final double value, final boolean strict) {
|
||||||
|
if (has(index)) {
|
||||||
|
return underlying.set(index, value, strict);
|
||||||
|
}
|
||||||
|
return extensionCheck(strict, index);
|
||||||
|
}
|
||||||
|
}
|
@ -48,19 +48,34 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
* @param array an int array
|
* @param array an int array
|
||||||
* @param length a length, not necessarily array.length
|
* @param length a length, not necessarily array.length
|
||||||
*/
|
*/
|
||||||
NumberArrayData(final double array[], final int length) {
|
NumberArrayData(final double[] array, final int length) {
|
||||||
super(length);
|
super(length);
|
||||||
assert array.length >= length;
|
assert array.length >= length;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getElementType() {
|
public final Class<?> getElementType() {
|
||||||
return double.class;
|
return double.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public final Class<?> getBoxedElementType() {
|
||||||
|
return Double.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getElementWeight() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
|
||||||
|
return otherData instanceof IntOrLongElements ? this : otherData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NumberArrayData copy() {
|
||||||
return new NumberArrayData(array.clone(), (int)length);
|
return new NumberArrayData(array.clone(), (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +103,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData convert(final Class<?> type) {
|
public ContinuousArrayData convert(final Class<?> type) {
|
||||||
if (type != Double.class && type != Integer.class && type != Long.class) {
|
if (type != Double.class && type != Integer.class && type != Long.class) {
|
||||||
final int len = (int)length;
|
final int len = (int)length;
|
||||||
return new ObjectArrayData(toObjectArray(false), len);
|
return new ObjectArrayData(toObjectArray(false), len);
|
||||||
@ -129,7 +144,7 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData shrink(final long newLength) {
|
public ArrayData shrink(final long newLength) {
|
||||||
Arrays.fill(array, (int) newLength, array.length, 0.0);
|
Arrays.fill(array, (int)newLength, array.length, 0.0);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,4 +349,26 @@ final class NumberArrayData extends ContinuousArrayData implements NumericElemen
|
|||||||
public Object fastPopObject() {
|
public Object fastPopObject() {
|
||||||
return fastPopDouble();
|
return fastPopDouble();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
final int otherLength = (int)otherData.length;
|
||||||
|
final int thisLength = (int)length;
|
||||||
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
|
final double[] otherArray = ((NumberArrayData)otherData).array;
|
||||||
|
final int newLength = otherLength + thisLength;
|
||||||
|
final double[] newArray = new double[ArrayData.alignUp(newLength)];
|
||||||
|
|
||||||
|
System.arraycopy(array, 0, newArray, 0, thisLength);
|
||||||
|
System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
|
||||||
|
|
||||||
|
return new NumberArrayData(newArray, newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
assert length <= array.length : length + " > " + array.length;
|
||||||
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,6 @@ package jdk.nashorn.internal.runtime.arrays;
|
|||||||
* Used for type checks that throw ClassCastExceptions and force relinks
|
* Used for type checks that throw ClassCastExceptions and force relinks
|
||||||
* for fast NativeArray specializations of builtin methods
|
* for fast NativeArray specializations of builtin methods
|
||||||
*/
|
*/
|
||||||
public interface NumericElements {
|
public interface NumericElements extends AnyElements {
|
||||||
//empty
|
//empty
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
|||||||
* Implementation of {@link ArrayData} as soon as an Object has been
|
* Implementation of {@link ArrayData} as soon as an Object has been
|
||||||
* written to the array
|
* written to the array
|
||||||
*/
|
*/
|
||||||
final class ObjectArrayData extends ContinuousArrayData {
|
final class ObjectArrayData extends ContinuousArrayData implements AnyElements {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The wrapped array
|
* The wrapped array
|
||||||
@ -49,19 +49,34 @@ final class ObjectArrayData extends ContinuousArrayData {
|
|||||||
* @param array an int array
|
* @param array an int array
|
||||||
* @param length a length, not necessarily array.length
|
* @param length a length, not necessarily array.length
|
||||||
*/
|
*/
|
||||||
ObjectArrayData(final Object array[], final int length) {
|
ObjectArrayData(final Object[] array, final int length) {
|
||||||
super(length);
|
super(length);
|
||||||
assert array.length >= length;
|
assert array.length >= length;
|
||||||
this.array = array;
|
this.array = array;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<?> getElementType() {
|
public final Class<?> getElementType() {
|
||||||
return Object.class;
|
return Object.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public final Class<?> getBoxedElementType() {
|
||||||
|
return getElementType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final int getElementWeight() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final ContinuousArrayData widest(final ContinuousArrayData otherData) {
|
||||||
|
return otherData instanceof NumericElements ? this : otherData;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ObjectArrayData copy() {
|
||||||
return new ObjectArrayData(array.clone(), (int)length);
|
return new ObjectArrayData(array.clone(), (int)length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,7 +94,7 @@ final class ObjectArrayData extends ContinuousArrayData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData convert(final Class<?> type) {
|
public ObjectArrayData convert(final Class<?> type) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,4 +340,26 @@ final class ObjectArrayData extends ContinuousArrayData {
|
|||||||
|
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ContinuousArrayData fastConcat(final ContinuousArrayData otherData) {
|
||||||
|
final int otherLength = (int)otherData.length;
|
||||||
|
final int thisLength = (int)length;
|
||||||
|
assert otherLength > 0 && thisLength > 0;
|
||||||
|
|
||||||
|
final Object[] otherArray = ((ObjectArrayData)otherData).array;
|
||||||
|
final int newLength = otherLength + thisLength;
|
||||||
|
final Object[] newArray = new Object[ArrayData.alignUp(newLength)];
|
||||||
|
|
||||||
|
System.arraycopy(array, 0, newArray, 0, thisLength);
|
||||||
|
System.arraycopy(otherArray, 0, newArray, thisLength, otherLength);
|
||||||
|
|
||||||
|
return new ObjectArrayData(newArray, newLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
assert length <= array.length : length + " > " + array.length;
|
||||||
|
return getClass().getSimpleName() + ':' + Arrays.toString(Arrays.copyOf(array, (int)length));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData copy() {
|
public TypedArrayData<T> copy() {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,7 +133,7 @@ public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayDa
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ArrayData convert(final Class<?> type) {
|
public TypedArrayData<T> convert(final Class<?> type) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
151
nashorn/test/script/basic/JDK-8061391.js
Normal file
151
nashorn/test/script/basic/JDK-8061391.js
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
/*
|
||||||
|
* 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-8061391 - Checks that the optimistic builtin for concat is semantically
|
||||||
|
* correct.
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var maxJavaInt = 0x7fffffff;
|
||||||
|
|
||||||
|
var ia = [1, 2, 3, 4];
|
||||||
|
var la = [maxJavaInt + 1000, maxJavaInt + 2000, maxJavaInt + 3000, maxJavaInt + 4000];
|
||||||
|
var da = [1.1, 2.2, 3.3, 4.4];
|
||||||
|
var oa = ["one", "two", "three", "four"];
|
||||||
|
|
||||||
|
var aa = [ia, la, da, oa];
|
||||||
|
|
||||||
|
function concats() {
|
||||||
|
print("shared callsite");
|
||||||
|
|
||||||
|
print(ia);
|
||||||
|
print(la);
|
||||||
|
print(da);
|
||||||
|
print(oa);
|
||||||
|
print(aa);
|
||||||
|
|
||||||
|
for (var i = 0; i < aa.length; i++) {
|
||||||
|
print(aa[i].concat(aa[i][0]));
|
||||||
|
for (var j = 0; j < aa.length ; j++) {
|
||||||
|
print(aa[i].concat(aa[j]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function concats_inline() {
|
||||||
|
print("separate callsites");
|
||||||
|
|
||||||
|
print(ia);
|
||||||
|
print(la);
|
||||||
|
print(da);
|
||||||
|
print(oa);
|
||||||
|
print(aa);
|
||||||
|
|
||||||
|
print(aa[0].concat(aa[0]));
|
||||||
|
print(aa[0].concat(aa[1]));
|
||||||
|
print(aa[0].concat(aa[2]));
|
||||||
|
print(aa[0].concat(aa[3]));
|
||||||
|
print(aa[0].concat(aa[0][0]));
|
||||||
|
|
||||||
|
print(aa[1].concat(aa[0]));
|
||||||
|
print(aa[1].concat(aa[1]));
|
||||||
|
print(aa[1].concat(aa[2]));
|
||||||
|
print(aa[1].concat(aa[3]));
|
||||||
|
print(aa[1].concat(aa[1][0]));
|
||||||
|
|
||||||
|
print(aa[2].concat(aa[0]));
|
||||||
|
print(aa[2].concat(aa[1]));
|
||||||
|
print(aa[2].concat(aa[2]));
|
||||||
|
print(aa[2].concat(aa[3]));
|
||||||
|
print(aa[2].concat(aa[2][0]));
|
||||||
|
|
||||||
|
print(aa[3].concat(aa[0]));
|
||||||
|
print(aa[3].concat(aa[1]));
|
||||||
|
print(aa[3].concat(aa[2]));
|
||||||
|
print(aa[3].concat(aa[3]));
|
||||||
|
print(aa[3].concat(aa[3][0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
concats();
|
||||||
|
concats_inline();
|
||||||
|
|
||||||
|
print();
|
||||||
|
var oldia = ia.slice(0); //clone ia
|
||||||
|
print("oldia = " + oldia);
|
||||||
|
ia[10] = "sparse";
|
||||||
|
print("oldia = " + oldia);
|
||||||
|
|
||||||
|
print();
|
||||||
|
print("Redoing with sparse arrays");
|
||||||
|
|
||||||
|
concats();
|
||||||
|
concats_inline();
|
||||||
|
|
||||||
|
ia = oldia;
|
||||||
|
print("Restored ia = " + ia);
|
||||||
|
|
||||||
|
function concat_expand() {
|
||||||
|
print("concat type expansion");
|
||||||
|
print(ia.concat(la));
|
||||||
|
print(ia.concat(da));
|
||||||
|
print(ia.concat(oa));
|
||||||
|
print(la.concat(ia));
|
||||||
|
print(la.concat(da));
|
||||||
|
print(la.concat(oa));
|
||||||
|
print(da.concat(ia));
|
||||||
|
print(da.concat(la));
|
||||||
|
print(da.concat(oa));
|
||||||
|
}
|
||||||
|
|
||||||
|
print();
|
||||||
|
concat_expand();
|
||||||
|
|
||||||
|
print();
|
||||||
|
|
||||||
|
function concat_varargs() {
|
||||||
|
print("concat varargs");
|
||||||
|
print(ia.concat(la)); //fast
|
||||||
|
print(ia.concat(la, da, oa)); //slow
|
||||||
|
var slow = ia.concat(1, maxJavaInt * 2, 4711.17, function() { print("hello, world") }); //slow
|
||||||
|
print(slow);
|
||||||
|
return slow;
|
||||||
|
}
|
||||||
|
|
||||||
|
var slow = concat_varargs();
|
||||||
|
|
||||||
|
print();
|
||||||
|
print("sanity checks");
|
||||||
|
slow.map(
|
||||||
|
function(elem) {
|
||||||
|
if (elem instanceof Function) {
|
||||||
|
elem();
|
||||||
|
} else {
|
||||||
|
print((typeof elem) + " = " + elem);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
print(ia.concat({key: "value"}));
|
||||||
|
print(ia.concat({key: "value"}, {key2: "value2"}));
|
138
nashorn/test/script/basic/JDK-8061391.js.EXPECTED
Normal file
138
nashorn/test/script/basic/JDK-8061391.js.EXPECTED
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
shared callsite
|
||||||
|
1,2,3,4
|
||||||
|
2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1,2,3,4,1
|
||||||
|
1,2,3,4,1,2,3,4
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,1.1,2.2,3.3,4.4
|
||||||
|
1,2,3,4,one,two,three,four
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1,2,3,4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,one,two,three,four
|
||||||
|
1.1,2.2,3.3,4.4,1.1
|
||||||
|
1.1,2.2,3.3,4.4,1,2,3,4
|
||||||
|
1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
|
||||||
|
1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
one,two,three,four,one
|
||||||
|
one,two,three,four,1,2,3,4
|
||||||
|
one,two,three,four,2147484647,2147485647,2147486647,2147487647
|
||||||
|
one,two,three,four,1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four,one,two,three,four
|
||||||
|
separate callsites
|
||||||
|
1,2,3,4
|
||||||
|
2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1,2,3,4,1,2,3,4
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,1.1,2.2,3.3,4.4
|
||||||
|
1,2,3,4,one,two,three,four
|
||||||
|
1,2,3,4,1
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1,2,3,4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,one,two,three,four
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647
|
||||||
|
1.1,2.2,3.3,4.4,1,2,3,4
|
||||||
|
1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
|
||||||
|
1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1.1,2.2,3.3,4.4,1.1
|
||||||
|
one,two,three,four,1,2,3,4
|
||||||
|
one,two,three,four,2147484647,2147485647,2147486647,2147487647
|
||||||
|
one,two,three,four,1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four,one,two,three,four
|
||||||
|
one,two,three,four,one
|
||||||
|
|
||||||
|
oldia = 1,2,3,4
|
||||||
|
oldia = 1,2,3,4
|
||||||
|
|
||||||
|
Redoing with sparse arrays
|
||||||
|
shared callsite
|
||||||
|
1,2,3,4,,,,,,,sparse
|
||||||
|
2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four
|
||||||
|
1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1,2,3,4,,,,,,,sparse,1
|
||||||
|
1,2,3,4,,,,,,,sparse,1,2,3,4,,,,,,,sparse
|
||||||
|
1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,,,,,,,sparse,1.1,2.2,3.3,4.4
|
||||||
|
1,2,3,4,,,,,,,sparse,one,two,three,four
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1,2,3,4,,,,,,,sparse
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,one,two,three,four
|
||||||
|
1.1,2.2,3.3,4.4,1.1
|
||||||
|
1.1,2.2,3.3,4.4,1,2,3,4,,,,,,,sparse
|
||||||
|
1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
|
||||||
|
1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
one,two,three,four,one
|
||||||
|
one,two,three,four,1,2,3,4,,,,,,,sparse
|
||||||
|
one,two,three,four,2147484647,2147485647,2147486647,2147487647
|
||||||
|
one,two,three,four,1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four,one,two,three,four
|
||||||
|
separate callsites
|
||||||
|
1,2,3,4,,,,,,,sparse
|
||||||
|
2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four
|
||||||
|
1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1,2,3,4,,,,,,,sparse,1,2,3,4,,,,,,,sparse
|
||||||
|
1,2,3,4,,,,,,,sparse,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,,,,,,,sparse,1.1,2.2,3.3,4.4
|
||||||
|
1,2,3,4,,,,,,,sparse,one,two,three,four
|
||||||
|
1,2,3,4,,,,,,,sparse,1
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1,2,3,4,,,,,,,sparse
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647,2147485647,2147486647,2147487647
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,one,two,three,four
|
||||||
|
2147484647,2147485647,2147486647,2147487647,2147484647
|
||||||
|
1.1,2.2,3.3,4.4,1,2,3,4,,,,,,,sparse
|
||||||
|
1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4,1.1,2.2,3.3,4.4
|
||||||
|
1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1.1,2.2,3.3,4.4,1.1
|
||||||
|
one,two,three,four,1,2,3,4,,,,,,,sparse
|
||||||
|
one,two,three,four,2147484647,2147485647,2147486647,2147487647
|
||||||
|
one,two,three,four,1.1,2.2,3.3,4.4
|
||||||
|
one,two,three,four,one,two,three,four
|
||||||
|
one,two,three,four,one
|
||||||
|
Restored ia = 1,2,3,4
|
||||||
|
|
||||||
|
concat type expansion
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,1.1,2.2,3.3,4.4
|
||||||
|
1,2,3,4,one,two,three,four
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1,2,3,4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4
|
||||||
|
2147484647,2147485647,2147486647,2147487647,one,two,three,four
|
||||||
|
1.1,2.2,3.3,4.4,1,2,3,4
|
||||||
|
1.1,2.2,3.3,4.4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
|
||||||
|
concat varargs
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647
|
||||||
|
1,2,3,4,2147484647,2147485647,2147486647,2147487647,1.1,2.2,3.3,4.4,one,two,three,four
|
||||||
|
1,2,3,4,1,4294967294,4711.17,function() { print("hello, world") }
|
||||||
|
|
||||||
|
sanity checks
|
||||||
|
number = 1
|
||||||
|
number = 2
|
||||||
|
number = 3
|
||||||
|
number = 4
|
||||||
|
number = 1
|
||||||
|
number = 4294967294
|
||||||
|
number = 4711.17
|
||||||
|
hello, world
|
||||||
|
1,2,3,4,[object Object]
|
||||||
|
1,2,3,4,[object Object],[object Object]
|
52
nashorn/test/script/basic/JDK-8061391_2.js
Normal file
52
nashorn/test/script/basic/JDK-8061391_2.js
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array extension check
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
var a = [1,2,3];
|
||||||
|
Object.preventExtensions(a);
|
||||||
|
try {
|
||||||
|
a[4] = 4;
|
||||||
|
print(a);
|
||||||
|
} catch (e) {
|
||||||
|
if (!(e instanceof TypeError)) {
|
||||||
|
print("TypeError expected but got e");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a[0] != 1) {
|
||||||
|
throw "element 0 is wrong";
|
||||||
|
}
|
||||||
|
if (a[1] != 2) {
|
||||||
|
throw "element 1 is wrong";
|
||||||
|
}
|
||||||
|
if (a[2] != 3) {
|
||||||
|
throw "element 2 is wrong";
|
||||||
|
}
|
||||||
|
|
44
nashorn/test/script/basic/JDK-8061391_3.js
Normal file
44
nashorn/test/script/basic/JDK-8061391_3.js
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2010, 2014, 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array extension check
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @run
|
||||||
|
*/
|
||||||
|
|
||||||
|
var a = [1,2,3];
|
||||||
|
Object.preventExtensions(a);
|
||||||
|
a[4] = 4;
|
||||||
|
print(a);
|
||||||
|
if (a[0] != 1) {
|
||||||
|
throw "element 0 is wrong";
|
||||||
|
}
|
||||||
|
if (a[1] != 2) {
|
||||||
|
throw "element 1 is wrong";
|
||||||
|
}
|
||||||
|
if (a[2] != 3) {
|
||||||
|
throw "element 2 is wrong";
|
||||||
|
}
|
||||||
|
|
1
nashorn/test/script/basic/JDK-8061391_3.js.EXPECTED
Normal file
1
nashorn/test/script/basic/JDK-8061391_3.js.EXPECTED
Normal file
@ -0,0 +1 @@
|
|||||||
|
1,2,3
|
Loading…
x
Reference in New Issue
Block a user