1 /*
2  * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package jdk.nashorn.internal.runtime.arrays;
27 
28 import static jdk.nashorn.internal.lookup.Lookup.MH;
29 import java.lang.invoke.MethodHandle;
30 import java.nio.Buffer;
31 import jdk.dynalink.CallSiteDescriptor;
32 import jdk.dynalink.linker.GuardedInvocation;
33 import jdk.dynalink.linker.LinkRequest;
34 import jdk.nashorn.internal.lookup.Lookup;
35 
36 /**
37  * The superclass of all ArrayData used by TypedArrays
38  *
39  * @param <T> buffer implementation
40  */
41 public abstract class TypedArrayData<T extends Buffer> extends ContinuousArrayData {
42 
43     /** wrapped native buffer */
44     protected final T nb;
45 
46     /**
47      * Constructor
48      * @param nb wrapped native buffer
49      * @param elementLength length in elements
50      */
TypedArrayData(final T nb, final int elementLength)51     protected TypedArrayData(final T nb, final int elementLength) {
52         super(elementLength); //TODO is this right?
53         this.nb = nb;
54     }
55 
56     /**
57      * Length in number of elements. Accessed from {@code ArrayBufferView}
58      * @return element length
59      */
getElementLength()60     public final int getElementLength() {
61         return (int)length();
62     }
63 
64     /**
65      * Is this an unsigned array data?
66      * @return true if unsigned
67      */
isUnsigned()68     public boolean isUnsigned() {
69         return false;
70     }
71 
72     /**
73      * Is this a clamped array data?
74      * @return true if clamped
75      */
isClamped()76     public boolean isClamped() {
77         return false;
78     }
79 
80     @Override
canDelete(final int index, final boolean strict)81     public boolean canDelete(final int index, final boolean strict) {
82         return false;
83     }
84 
85     @Override
canDelete(final long longIndex, final boolean strict)86     public boolean canDelete(final long longIndex, final boolean strict) {
87         return false;
88     }
89 
90     @Override
copy()91     public TypedArrayData<T> copy() {
92         throw new UnsupportedOperationException();
93     }
94 
95     @Override
asObjectArray()96     public Object[] asObjectArray() {
97         throw new UnsupportedOperationException();
98     }
99 
100     @Override
shiftLeft(final int by)101     public ArrayData shiftLeft(final int by) {
102         throw new UnsupportedOperationException();
103     }
104 
105     @Override
shiftRight(final int by)106     public ArrayData shiftRight(final int by) {
107         throw new UnsupportedOperationException();
108     }
109 
110     @Override
ensure(final long safeIndex)111     public ArrayData ensure(final long safeIndex) {
112         return this;
113     }
114 
115     @Override
shrink(final long newLength)116     public ArrayData shrink(final long newLength) {
117         throw new UnsupportedOperationException();
118     }
119 
120     @Override
has(final int index)121     public final boolean has(final int index) {
122         return 0 <= index && index < length();
123     }
124 
125     @Override
delete(final int index)126     public ArrayData delete(final int index) {
127         return this;
128     }
129 
130     @Override
delete(final long fromIndex, final long toIndex)131     public ArrayData delete(final long fromIndex, final long toIndex) {
132         return this;
133     }
134 
135     @Override
convert(final Class<?> type)136     public TypedArrayData<T> convert(final Class<?> type) {
137         throw new UnsupportedOperationException();
138     }
139 
140     @Override
pop()141     public Object pop() {
142         throw new UnsupportedOperationException();
143     }
144 
145     @Override
slice(final long from, final long to)146     public ArrayData slice(final long from, final long to) {
147         throw new UnsupportedOperationException();
148     }
149 
150     /**
151      * Element getter method handle
152      * @return getter
153      */
getGetElem()154     protected abstract MethodHandle getGetElem();
155 
156     /**
157      * Element setter method handle
158      * @return setter
159      */
getSetElem()160     protected abstract MethodHandle getSetElem();
161 
162     @Override
getElementGetter(final Class<?> returnType, final int programPoint)163     public MethodHandle getElementGetter(final Class<?> returnType, final int programPoint) {
164         final MethodHandle getter = getContinuousElementGetter(getClass(), getGetElem(), returnType, programPoint);
165         if (getter != null) {
166             return Lookup.filterReturnType(getter, returnType);
167         }
168         return getter;
169     }
170 
171     @Override
getElementSetter(final Class<?> elementType)172     public MethodHandle getElementSetter(final Class<?> elementType) {
173         return getContinuousElementSetter(getClass(), Lookup.filterArgumentType(getSetElem(), 2, elementType), elementType);
174     }
175 
176     @Override
getContinuousElementSetter(final Class<? extends ContinuousArrayData> clazz, final MethodHandle setHas, final Class<?> elementType)177     protected MethodHandle getContinuousElementSetter(final Class<? extends ContinuousArrayData> clazz, final MethodHandle setHas, final Class<?> elementType) {
178         final MethodHandle mh = Lookup.filterArgumentType(setHas, 2, elementType);
179         return MH.asType(mh, mh.type().changeParameterType(0, clazz));
180     }
181 
182     @Override
findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request)183     public GuardedInvocation findFastGetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) {
184         final GuardedInvocation inv = super.findFastGetIndexMethod(clazz, desc, request);
185 
186         if (inv != null) {
187             return inv;
188         }
189 
190         return null;
191     }
192 
193     @Override
findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request)194     public GuardedInvocation findFastSetIndexMethod(final Class<? extends ArrayData> clazz, final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
195         final GuardedInvocation inv = super.findFastSetIndexMethod(clazz, desc, request);
196 
197         if (inv != null) {
198             return inv;
199         }
200 
201         return null;
202     }
203 
204 }
205