44 import jdk.nashorn.internal.runtime.ScriptRuntime;
45 import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
46
47 /**
48 * ArrayData - abstraction for wrapping array elements
49 */
50 public abstract class ArrayData {
51 /** Minimum chunk size for underlying arrays */
52 protected static final int CHUNK_SIZE = 32;
53
54 /** Mask for getting a chunk */
55 protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
56
57 /** Untouched data - still link callsites as IntArrayData, but expands to
58 * a proper ArrayData when we try to write to it */
59 public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
60
61 /**
62 * Length of the array data. Not necessarily length of the wrapped array.
63 * This is private to ensure that no one in a subclass is able to touch the length
64 * without going through {@link setLength}. This is used to implement
65 * {@link LengthNotWritableFilter}s, ensuring that there are no ways past
66 * a {@link setLength} function replaced by a nop
67 */
68 private long length;
69
70 /**
71 * Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
72 * of the wrong type
73 */
74 protected static final CompilerConstants.Call THROW_UNWARRANTED = staticCall(MethodHandles.lookup(), ArrayData.class, "throwUnwarranted", void.class, ArrayData.class, int.class, int.class);
75
76 /**
77 * Immutable empty array to get ScriptObjects started.
78 * Use the same array and convert it to mutable as soon as it is modified
79 */
80 private static class UntouchedArrayData extends ContinuousArrayData {
81 private UntouchedArrayData() {
82 this(0);
83 }
84
85 private UntouchedArrayData(final int length) {
86 super(length);
87 }
88
89 private ArrayData toRealArrayData() {
90 return toRealArrayData(0);
91 }
92
93 private ArrayData toRealArrayData(final int index) {
94 final IntArrayData newData = new IntArrayData(index + 1);
95 if (index == 0) {
96 return newData;
97 }
98 return new DeletedRangeArrayFilter(newData, 0, index);
99 }
100
101 @Override
102 public ContinuousArrayData copy() {
103 return new UntouchedArrayData((int)length());
104 }
105
106 @Override
107 public Object asArrayOfType(final Class<?> componentType) {
108 return Array.newInstance(componentType, 0);
109 }
110
111 @Override
112 public Object[] asObjectArray() {
113 return ScriptRuntime.EMPTY_ARRAY;
114 }
115
116 @Override
117 public ArrayData ensure(final long safeIndex) {
118 if (safeIndex > 0L) {
119 if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
120 return new SparseArrayData(this, safeIndex + 1);
121 }
122 //known to fit in int
123 return toRealArrayData((int)safeIndex).ensure(safeIndex);
229
230 @Override
231 public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
232 return null;
233 }
234
235 @Override
236 public MethodHandle getElementSetter(final Class<?> elementType) {
237 return null;
238 }
239
240 @Override
241 public Class<?> getElementType() {
242 return int.class;
243 }
244
245 @Override
246 public Class<?> getBoxedElementType() {
247 return Integer.class;
248 }
249 };
250
251 /**
252 * Constructor
253 * @param length Virtual length of the array.
254 */
255 protected ArrayData(final long length) {
256 this.length = length;
257 }
258
259 /**
260 * Factory method for unspecified array - start as int
261 * @return ArrayData
262 */
263 public final static ArrayData initialArray() {
264 return new IntArrayData();
265 }
266
267 /**
268 * Unwarranted thrower
269 *
|
44 import jdk.nashorn.internal.runtime.ScriptRuntime;
45 import jdk.nashorn.internal.runtime.UnwarrantedOptimismException;
46
47 /**
48 * ArrayData - abstraction for wrapping array elements
49 */
50 public abstract class ArrayData {
51 /** Minimum chunk size for underlying arrays */
52 protected static final int CHUNK_SIZE = 32;
53
54 /** Mask for getting a chunk */
55 protected static final int CHUNK_MASK = CHUNK_SIZE - 1;
56
57 /** Untouched data - still link callsites as IntArrayData, but expands to
58 * a proper ArrayData when we try to write to it */
59 public static final ArrayData EMPTY_ARRAY = new UntouchedArrayData();
60
61 /**
62 * Length of the array data. Not necessarily length of the wrapped array.
63 * This is private to ensure that no one in a subclass is able to touch the length
64 * without going through {@link #setLength}. This is used to implement
65 * {@link LengthNotWritableFilter}s, ensuring that there are no ways past
66 * a {@link #setLength} function replaced by a nop
67 */
68 private long length;
69
70 /**
71 * Method handle to throw an {@link UnwarrantedOptimismException} when getting an element
72 * of the wrong type
73 */
74 protected static final CompilerConstants.Call THROW_UNWARRANTED = staticCall(MethodHandles.lookup(), ArrayData.class, "throwUnwarranted", void.class, ArrayData.class, int.class, int.class);
75
76 /**
77 * Immutable empty array to get ScriptObjects started.
78 * Use the same array and convert it to mutable as soon as it is modified
79 */
80 private static class UntouchedArrayData extends ContinuousArrayData {
81 private UntouchedArrayData() {
82 super(0);
83 }
84
85 private ArrayData toRealArrayData() {
86 return toRealArrayData(0);
87 }
88
89 private ArrayData toRealArrayData(final int index) {
90 final IntArrayData newData = new IntArrayData(index + 1);
91 if (index == 0) {
92 return newData;
93 }
94 return new DeletedRangeArrayFilter(newData, 0, index);
95 }
96
97 @Override
98 public ContinuousArrayData copy() {
99 assert length() == 0;
100 return this;
101 }
102
103 @Override
104 public Object asArrayOfType(final Class<?> componentType) {
105 return Array.newInstance(componentType, 0);
106 }
107
108 @Override
109 public Object[] asObjectArray() {
110 return ScriptRuntime.EMPTY_ARRAY;
111 }
112
113 @Override
114 public ArrayData ensure(final long safeIndex) {
115 if (safeIndex > 0L) {
116 if (safeIndex >= SparseArrayData.MAX_DENSE_LENGTH) {
117 return new SparseArrayData(this, safeIndex + 1);
118 }
119 //known to fit in int
120 return toRealArrayData((int)safeIndex).ensure(safeIndex);
226
227 @Override
228 public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
229 return null;
230 }
231
232 @Override
233 public MethodHandle getElementSetter(final Class<?> elementType) {
234 return null;
235 }
236
237 @Override
238 public Class<?> getElementType() {
239 return int.class;
240 }
241
242 @Override
243 public Class<?> getBoxedElementType() {
244 return Integer.class;
245 }
246 }
247
248 /**
249 * Constructor
250 * @param length Virtual length of the array.
251 */
252 protected ArrayData(final long length) {
253 this.length = length;
254 }
255
256 /**
257 * Factory method for unspecified array - start as int
258 * @return ArrayData
259 */
260 public final static ArrayData initialArray() {
261 return new IntArrayData();
262 }
263
264 /**
265 * Unwarranted thrower
266 *
|