8020132: Big object literal with numerical keys exceeds method size
Reviewed-by: lagergren, sundar
This commit is contained in:
parent
c9efbba43f
commit
24adb234a8
@ -45,6 +45,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.methodDescriptor;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.staticField;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL;
|
||||
import static jdk.nashorn.internal.ir.Symbol.IS_TEMP;
|
||||
import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_FAST_SCOPE;
|
||||
@ -131,6 +132,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
import jdk.nashorn.internal.runtime.Undefined;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
|
||||
|
||||
/**
|
||||
@ -1262,7 +1264,11 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
classEmitter.needGetConstantMethod(cls);
|
||||
} else {
|
||||
method.loadConstants().load(index).arrayload();
|
||||
if (cls != Object.class) {
|
||||
if (object instanceof ArrayData) {
|
||||
// avoid cast to non-public ArrayData subclass
|
||||
method.checkcast(ArrayData.class);
|
||||
method.invoke(virtualCallNoLookup(ArrayData.class, "copy", ArrayData.class));
|
||||
} else if (cls != Object.class) {
|
||||
method.checkcast(cls);
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,15 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor;
|
||||
import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount;
|
||||
import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.Symbol;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
||||
@ -129,12 +132,12 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
|
||||
final T value = valueIter.next();
|
||||
|
||||
if (symbol != null && value != null) {
|
||||
final int index = ArrayIndex.getArrayIndex(key);
|
||||
final int index = getArrayIndex(key);
|
||||
|
||||
if (index < 0) {
|
||||
if (!isValidArrayIndex(index)) {
|
||||
putField(method, key, symbol.getFieldIndex(), value);
|
||||
} else {
|
||||
putSlot(method, index, value);
|
||||
putSlot(method, ArrayIndex.toLongIndex(index), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,9 +180,13 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator {
|
||||
* @param index Slot index.
|
||||
* @param value Value to store.
|
||||
*/
|
||||
private void putSlot(final MethodEmitter method, final int index, final T value) {
|
||||
private void putSlot(final MethodEmitter method, final long index, final T value) {
|
||||
method.dup();
|
||||
method.load(index);
|
||||
if (JSType.isRepresentableAsInt(index)) {
|
||||
method.load((int) index);
|
||||
} else {
|
||||
method.load(index);
|
||||
}
|
||||
loadValue(value);
|
||||
method.dynamicSetIndex(callSiteFlags);
|
||||
}
|
||||
|
@ -25,13 +25,15 @@
|
||||
|
||||
package jdk.nashorn.internal.codegen;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndex;
|
||||
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import jdk.nashorn.internal.ir.Symbol;
|
||||
import jdk.nashorn.internal.runtime.AccessorProperty;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
||||
|
||||
/**
|
||||
* Class that creates PropertyMap sent to script object constructors.
|
||||
@ -76,7 +78,7 @@ public class MapCreator {
|
||||
final String key = keys.get(i);
|
||||
final Symbol symbol = symbols.get(i);
|
||||
|
||||
if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) {
|
||||
if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) {
|
||||
properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex()));
|
||||
}
|
||||
}
|
||||
@ -93,7 +95,7 @@ public class MapCreator {
|
||||
final String key = keys.get(i);
|
||||
final Symbol symbol = symbols.get(i);
|
||||
|
||||
if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) {
|
||||
if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) {
|
||||
properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), spillIndex++));
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,13 @@
|
||||
package jdk.nashorn.internal.codegen;
|
||||
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup;
|
||||
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
|
||||
import static jdk.nashorn.internal.codegen.types.Type.OBJECT;
|
||||
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import jdk.nashorn.internal.codegen.types.Type;
|
||||
import jdk.nashorn.internal.ir.Expression;
|
||||
import jdk.nashorn.internal.ir.LiteralNode;
|
||||
@ -36,6 +40,8 @@ import jdk.nashorn.internal.ir.Symbol;
|
||||
import jdk.nashorn.internal.runtime.Property;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayIndex;
|
||||
import jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
/**
|
||||
@ -63,56 +69,82 @@ public class SpillObjectCreator extends ObjectCreator {
|
||||
protected void makeObject(final MethodEmitter method) {
|
||||
assert !isScope() : "spill scope objects are not currently supported";
|
||||
|
||||
final int length = keys.size();
|
||||
final Object[] presetValues = new Object[propertyMap.size()];
|
||||
final Class<?> clazz = JO.class;
|
||||
final int length = keys.size();
|
||||
final Object[] presetValues = new Object[length];
|
||||
final Set<Integer> postsetValues = new LinkedHashSet<>();
|
||||
final int callSiteFlags = codegen.getCallSiteFlags();
|
||||
ArrayData arrayData = ArrayData.allocate(new Object[0]);
|
||||
|
||||
// Compute constant values
|
||||
// Compute constant property values
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String key = keys.get(i);
|
||||
final Property property = propertyMap.findProperty(key);
|
||||
final Expression value = values.get(i);
|
||||
|
||||
if (value == null) {
|
||||
continue; // getter or setter
|
||||
}
|
||||
|
||||
final Object constantValue = LiteralNode.objectAsConstant(value);
|
||||
if (constantValue == LiteralNode.POSTSET_MARKER) {
|
||||
postsetValues.add(i);
|
||||
continue;
|
||||
}
|
||||
|
||||
final Property property = propertyMap.findProperty(key);
|
||||
if (property != null) {
|
||||
presetValues[property.getSlot()] = LiteralNode.objectAsConstant(values.get(i));
|
||||
// normal property key
|
||||
presetValues[property.getSlot()] = constantValue;
|
||||
} else {
|
||||
// array index key
|
||||
final long oldLength = arrayData.length();
|
||||
final int index = ArrayIndex.getArrayIndex(key);
|
||||
assert ArrayIndex.isValidArrayIndex(index);
|
||||
final long longIndex = ArrayIndex.toLongIndex(index);
|
||||
if (longIndex >= oldLength) {
|
||||
arrayData = arrayData.ensure(longIndex);
|
||||
}
|
||||
arrayData = arrayData.set(index, constantValue, false);
|
||||
if (longIndex > oldLength) {
|
||||
arrayData = arrayData.delete(oldLength, longIndex - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
method._new(clazz).dup();
|
||||
// create object and invoke constructor
|
||||
method._new(JO.class).dup();
|
||||
codegen.loadConstant(propertyMap);
|
||||
|
||||
method.invoke(constructorNoLookup(JO.class, PropertyMap.class));
|
||||
|
||||
// Set spill array with preset values
|
||||
method.dup();
|
||||
codegen.loadConstant(presetValues);
|
||||
method.putField(Type.getInternalName(ScriptObject.class), "spill", Type.OBJECT_ARRAY.getDescriptor());
|
||||
|
||||
// Set array data if any
|
||||
if (arrayData.length() > 0) {
|
||||
method.dup();
|
||||
codegen.loadConstant(arrayData);
|
||||
method.invoke(virtualCallNoLookup(ScriptObject.class, "setArray",void.class, ArrayData.class));
|
||||
}
|
||||
|
||||
// Create properties with non-constant values
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (int i : postsetValues) {
|
||||
final String key = keys.get(i);
|
||||
final Property property = propertyMap.findProperty(key);
|
||||
|
||||
if (property != null && presetValues[property.getSlot()] == LiteralNode.POSTSET_MARKER) {
|
||||
if (property == null) {
|
||||
final int index = ArrayIndex.getArrayIndex(key);
|
||||
assert ArrayIndex.isValidArrayIndex(index);
|
||||
method.dup();
|
||||
method.load(ArrayIndex.toLongIndex(index));
|
||||
codegen.load(values.get(i));
|
||||
method.dynamicSetIndex(callSiteFlags);
|
||||
} else {
|
||||
method.dup();
|
||||
method.getField(Type.getInternalName(ScriptObject.class), "spill", Type.OBJECT_ARRAY.getDescriptor());
|
||||
method.load(property.getSlot());
|
||||
codegen.load(values.get(i)).convert(OBJECT);
|
||||
method.arraystore();
|
||||
presetValues[property.getSlot()] = null;
|
||||
}
|
||||
}
|
||||
|
||||
method.putField(Type.typeFor(ScriptObject.class).getInternalName(), "spill", Type.OBJECT_ARRAY.getDescriptor());
|
||||
final int callSiteFlags = codegen.getCallSiteFlags();
|
||||
|
||||
// Assign properties with valid array index keys
|
||||
for (int i = 0; i < length; i++) {
|
||||
final String key = keys.get(i);
|
||||
final Property property = propertyMap.findProperty(key);
|
||||
final Expression value = values.get(i);
|
||||
|
||||
if (property == null && value != null) {
|
||||
method.dup();
|
||||
method.load(keys.get(i));
|
||||
codegen.load(value);
|
||||
method.dynamicSetIndex(callSiteFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,6 +115,11 @@ abstract class ArrayBufferView extends ScriptObject {
|
||||
this.elementLength = elementLength;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
throw new UnsupportedOperationException(); // Not used for ArrayBuffers
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] asObjectArray() {
|
||||
final Object[] array = new Object[elementLength];
|
||||
|
@ -44,26 +44,29 @@ import jdk.nashorn.tools.Shell;
|
||||
*
|
||||
*/
|
||||
abstract class NashornLoader extends SecureClassLoader {
|
||||
private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects";
|
||||
private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime";
|
||||
private static final String OBJECTS_PKG = "jdk.nashorn.internal.objects";
|
||||
private static final String RUNTIME_PKG = "jdk.nashorn.internal.runtime";
|
||||
private static final String RUNTIME_ARRAYS_PKG = "jdk.nashorn.internal.runtime.arrays";
|
||||
private static final String RUNTIME_LINKER_PKG = "jdk.nashorn.internal.runtime.linker";
|
||||
private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts";
|
||||
private static final String SCRIPTS_PKG = "jdk.nashorn.internal.scripts";
|
||||
|
||||
private static final Permission[] SCRIPT_PERMISSIONS;
|
||||
static {
|
||||
SCRIPT_PERMISSIONS = new Permission[4];
|
||||
|
||||
static {
|
||||
/*
|
||||
* Generated classes get access to runtime, runtime.linker, objects, scripts packages.
|
||||
* Note that the actual scripts can not access these because Java.type, Packages
|
||||
* prevent these restricted packages. And Java reflection and JSR292 access is prevented
|
||||
* for scripts. In other words, nashorn generated portions of script classes can access
|
||||
* clases in these implementation packages.
|
||||
* classes in these implementation packages.
|
||||
*/
|
||||
SCRIPT_PERMISSIONS[0] = new RuntimePermission("accessClassInPackage." + RUNTIME_PKG);
|
||||
SCRIPT_PERMISSIONS[1] = new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG);
|
||||
SCRIPT_PERMISSIONS[2] = new RuntimePermission("accessClassInPackage." + OBJECTS_PKG);
|
||||
SCRIPT_PERMISSIONS[3] = new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG);
|
||||
SCRIPT_PERMISSIONS = new Permission[] {
|
||||
new RuntimePermission("accessClassInPackage." + RUNTIME_PKG),
|
||||
new RuntimePermission("accessClassInPackage." + RUNTIME_LINKER_PKG),
|
||||
new RuntimePermission("accessClassInPackage." + OBJECTS_PKG),
|
||||
new RuntimePermission("accessClassInPackage." + SCRIPTS_PKG),
|
||||
new RuntimePermission("accessClassInPackage." + RUNTIME_ARRAYS_PKG)
|
||||
};
|
||||
}
|
||||
|
||||
private final Context context;
|
||||
@ -97,6 +100,7 @@ abstract class NashornLoader extends SecureClassLoader {
|
||||
final String pkgName = name.substring(0, i);
|
||||
switch (pkgName) {
|
||||
case RUNTIME_PKG:
|
||||
case RUNTIME_ARRAYS_PKG:
|
||||
case RUNTIME_LINKER_PKG:
|
||||
case OBJECTS_PKG:
|
||||
case SCRIPTS_PKG:
|
||||
|
@ -56,7 +56,7 @@ public abstract class ArrayData {
|
||||
* Constructor
|
||||
* @param length Virtual length of the array.
|
||||
*/
|
||||
public ArrayData(final long length) {
|
||||
protected ArrayData(final long length) {
|
||||
this.length = length;
|
||||
}
|
||||
|
||||
@ -182,6 +182,14 @@ public abstract class ArrayData {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a copy of the array that can be modified without affecting this instance.
|
||||
* It is safe to return themselves for immutable subclasses.
|
||||
*
|
||||
* @return a new array
|
||||
*/
|
||||
public abstract ArrayData copy();
|
||||
|
||||
/**
|
||||
* Return a copy of the array data as an Object array.
|
||||
*
|
||||
|
@ -177,15 +177,5 @@ public final class ArrayIndex {
|
||||
return index & JSType.MAX_UINT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a key string represents a valid array index in JavaScript and is small enough
|
||||
* to fit into a positive int.
|
||||
*
|
||||
* @param key the key
|
||||
* @return true if key works as a valid int array index
|
||||
*/
|
||||
public static boolean isIntArrayIndex(final String key) {
|
||||
return getArrayIndex(key) >= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
/**
|
||||
* Iterator over a NativeArray
|
||||
*/
|
||||
public class ArrayIterator extends ArrayLikeIterator<Object> {
|
||||
class ArrayIterator extends ArrayLikeIterator<Object> {
|
||||
|
||||
/** Array {@link ScriptObject} to iterate over */
|
||||
protected final ScriptObject array;
|
||||
|
@ -43,6 +43,13 @@ final class DeletedArrayFilter extends ArrayFilter {
|
||||
this.deleted = new BitVector(underlying.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
DeletedArrayFilter copy = new DeletedArrayFilter(underlying.copy());
|
||||
copy.getDeleted().copy(deleted);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] asObjectArray() {
|
||||
final Object[] value = super.asObjectArray();
|
||||
|
@ -49,6 +49,11 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
||||
return lo <= index && index <= hi;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new DeletedRangeArrayFilter(underlying.copy(), lo, hi);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] asObjectArray() {
|
||||
final Object[] value = super.asObjectArray();
|
||||
@ -191,11 +196,7 @@ final class DeletedRangeArrayFilter extends ArrayFilter {
|
||||
|
||||
private ArrayData getDeletedArrayFilter() {
|
||||
final ArrayData deleteFilter = new DeletedArrayFilter(getUnderlying());
|
||||
|
||||
for (long i = lo; i <= hi; i++) {
|
||||
deleteFilter.delete((int) i);
|
||||
}
|
||||
|
||||
deleteFilter.delete(lo, hi);
|
||||
return deleteFilter;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,11 @@ final class FrozenArrayFilter extends SealedArrayFilter {
|
||||
super(underlying);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor getDescriptor(final GlobalObject global, final int index) {
|
||||
return global.newDataDescriptor(getObject(index), false, true, false);
|
||||
|
@ -33,7 +33,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
* Implementation of {@link ArrayData} as soon as an int has been
|
||||
* written to the array. This is the default data for new arrays
|
||||
*/
|
||||
public final class IntArrayData extends ArrayData {
|
||||
final class IntArrayData extends ArrayData {
|
||||
/**
|
||||
* The wrapped array
|
||||
*/
|
||||
@ -55,10 +55,13 @@ public final class IntArrayData extends ArrayData {
|
||||
*/
|
||||
IntArrayData(final int array[], final int length) {
|
||||
super(length);
|
||||
assert array.length >= length;
|
||||
this.array = array;
|
||||
if (array.length > length) {
|
||||
Arrays.fill(array, length, array.length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new IntArrayData(array.clone(), (int) length());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -46,9 +46,15 @@ final class LongArrayData extends ArrayData {
|
||||
*/
|
||||
LongArrayData(final long array[], final int length) {
|
||||
super(length);
|
||||
assert array.length >= length;
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new LongArrayData(array.clone(), (int) length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] asObjectArray() {
|
||||
return toObjectArray(array, (int) length());
|
||||
|
@ -46,6 +46,11 @@ final class NoTypeArrayData extends ArrayData {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new NoTypeArrayData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object asArrayOfType(final Class<?> componentType) {
|
||||
return Array.newInstance(componentType, 0);
|
||||
|
@ -46,10 +46,13 @@ final class NumberArrayData extends ArrayData {
|
||||
*/
|
||||
NumberArrayData(final double array[], final int length) {
|
||||
super(length);
|
||||
assert array.length >= length;
|
||||
this.array = array;
|
||||
if (array.length > length) {
|
||||
Arrays.fill(array, length, array.length, 0.0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new NumberArrayData(array.clone(), (int) length());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,10 +47,13 @@ final class ObjectArrayData extends ArrayData {
|
||||
*/
|
||||
ObjectArrayData(final Object array[], final int length) {
|
||||
super(length);
|
||||
assert array.length >= length;
|
||||
this.array = array;
|
||||
if (array.length > length) {
|
||||
Arrays.fill(array, length, array.length, ScriptRuntime.UNDEFINED);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new ObjectArrayData(array.clone(), (int) length());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -109,9 +112,6 @@ final class ObjectArrayData extends ArrayData {
|
||||
|
||||
@Override
|
||||
public ArrayData set(final int index, final Object value, final boolean strict) {
|
||||
if (value == ScriptRuntime.UNDEFINED) {
|
||||
return new UndefinedArrayFilter(this).set(index, value, strict);
|
||||
}
|
||||
array[index] = value;
|
||||
setLength(Math.max(index + 1, length()));
|
||||
return this;
|
||||
|
@ -30,7 +30,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
/**
|
||||
* Reverse iterator over a NativeArray
|
||||
*/
|
||||
public final class ReverseArrayIterator extends ArrayIterator {
|
||||
final class ReverseArrayIterator extends ArrayIterator {
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -38,6 +38,11 @@ class SealedArrayFilter extends ArrayFilter {
|
||||
super(underlying);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new SealedArrayFilter(underlying.copy());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData slice(final long from, final long to) {
|
||||
return getUnderlying().slice(from, to);
|
||||
|
@ -41,22 +41,26 @@ class SparseArrayData extends ArrayData {
|
||||
private ArrayData underlying;
|
||||
|
||||
/** Maximum length to be stored in the array. */
|
||||
|
||||
private final long maxDenseLength;
|
||||
|
||||
/** Sparse elements. */
|
||||
private TreeMap<Long, Object> sparseMap = new TreeMap<>();
|
||||
private TreeMap<Long, Object> sparseMap;
|
||||
|
||||
SparseArrayData(final ArrayData underlying) {
|
||||
super(underlying.length());
|
||||
this.underlying = underlying;
|
||||
this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
|
||||
SparseArrayData(final ArrayData underlying, final long length) {
|
||||
this(underlying, length, new TreeMap<Long, Object>());
|
||||
}
|
||||
|
||||
SparseArrayData(final ArrayData array, final long length) {
|
||||
this(array);
|
||||
assert array.length() <= length;
|
||||
super.setLength(length);
|
||||
SparseArrayData(final ArrayData underlying, final long length, final TreeMap<Long, Object> sparseMap) {
|
||||
super(length);
|
||||
assert underlying.length() <= length;
|
||||
this.underlying = underlying;
|
||||
this.maxDenseLength = Math.max(MAX_DENSE_LENGTH, underlying.length());
|
||||
this.sparseMap = sparseMap;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
return new SparseArrayData(underlying.copy(), length(), new TreeMap<Long, Object>(sparseMap));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -43,6 +43,13 @@ final class UndefinedArrayFilter extends ArrayFilter {
|
||||
this.undefined = new BitVector(underlying.length());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ArrayData copy() {
|
||||
UndefinedArrayFilter copy = new UndefinedArrayFilter(underlying.copy());
|
||||
copy.getUndefined().copy(undefined);
|
||||
return copy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] asObjectArray() {
|
||||
final Object[] value = super.asObjectArray();
|
||||
|
23992
nashorn/test/script/basic/JDK-8020132.js
Normal file
23992
nashorn/test/script/basic/JDK-8020132.js
Normal file
File diff suppressed because it is too large
Load Diff
18
nashorn/test/script/basic/JDK-8020132.js.EXPECTED
Normal file
18
nashorn/test/script/basic/JDK-8020132.js.EXPECTED
Normal file
@ -0,0 +1,18 @@
|
||||
19970
|
||||
58562
|
||||
undefined
|
||||
null
|
||||
58565
|
||||
19970
|
||||
58565
|
||||
23940
|
||||
0
|
||||
19970
|
||||
58562
|
||||
undefined
|
||||
null
|
||||
58565
|
||||
19970
|
||||
58565
|
||||
23940
|
||||
0
|
Loading…
x
Reference in New Issue
Block a user