NativeUint8Array.java revision 1062:f9ed1ca59030
138517Sdfr/*
238517Sdfr * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
338517Sdfr * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
438517Sdfr *
538517Sdfr * This code is free software; you can redistribute it and/or modify it
638517Sdfr * under the terms of the GNU General Public License version 2 only, as
738517Sdfr * published by the Free Software Foundation.  Oracle designates this
838517Sdfr * particular file as subject to the "Classpath" exception as provided
938517Sdfr * by Oracle in the LICENSE file that accompanied this code.
1038517Sdfr *
1138517Sdfr * This code is distributed in the hope that it will be useful, but WITHOUT
1238517Sdfr * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1338517Sdfr * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1438517Sdfr * version 2 for more details (a copy is included in the LICENSE file that
1538517Sdfr * accompanied this code).
1638517Sdfr *
1738517Sdfr * You should have received a copy of the GNU General Public License version
1838517Sdfr * 2 along with this work; if not, write to the Free Software Foundation,
1938517Sdfr * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2038517Sdfr *
2138517Sdfr * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2238517Sdfr * or visit www.oracle.com if you need additional information or have any
2338517Sdfr * questions.
2438517Sdfr */
2538517Sdfr
2650477Speterpackage jdk.nashorn.internal.objects;
2738517Sdfr
2838517Sdfrimport static jdk.nashorn.internal.codegen.CompilerConstants.specialCall;
2938517Sdfr
3038517Sdfrimport java.lang.invoke.MethodHandle;
3138517Sdfrimport java.lang.invoke.MethodHandles;
3238517Sdfrimport java.nio.ByteBuffer;
3348797Salcimport jdk.nashorn.internal.objects.annotations.Attribute;
3438517Sdfrimport jdk.nashorn.internal.objects.annotations.Constructor;
3548797Salcimport jdk.nashorn.internal.objects.annotations.Function;
3648797Salcimport jdk.nashorn.internal.objects.annotations.Property;
3748797Salcimport jdk.nashorn.internal.objects.annotations.ScriptClass;
3848797Salcimport jdk.nashorn.internal.objects.annotations.Where;
3948797Salcimport jdk.nashorn.internal.runtime.JSType;
4048797Salcimport jdk.nashorn.internal.runtime.PropertyMap;
4148797Salcimport jdk.nashorn.internal.runtime.ScriptObject;
4248797Salcimport jdk.nashorn.internal.runtime.arrays.ArrayData;
4348797Salcimport jdk.nashorn.internal.runtime.arrays.TypedArrayData;
4448797Salc
4548797Salc/**
4648797Salc * Uint8 array for TypedArray extension
4748797Salc */
4848797Salc@ScriptClass("Uint8Array")
4966695Sjhbpublic final class NativeUint8Array extends ArrayBufferView {
5048797Salc
5148797Salc    /**
5248797Salc     * The size in bytes of each element in the array.
5348797Salc     */
5448797Salc    @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
5566695Sjhb    public static final int BYTES_PER_ELEMENT = 1;
5638517Sdfr
5738517Sdfr    // initialized by nasgen
5848797Salc    @SuppressWarnings("unused")
5949999Salc    private static PropertyMap $nasgenmap$;
6049999Salc
6149999Salc    private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
6249999Salc        @Override
6349999Salc        public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
6449999Salc            return new NativeUint8Array(buffer, byteOffset, length);
6548797Salc        }
6649999Salc
6749999Salc        @Override
6867351Sjhb        public Uint8ArrayData createArrayData(final ByteBuffer nb, final int start, final int end) {
6949999Salc            return new Uint8ArrayData(nb, start, end);
7066695Sjhb        }
7165514Sphk
7271085Sjhb        @Override
7371085Sjhb        public String getClassName() {
7471085Sjhb            return "Uint8Array";
7571085Sjhb        }
7649999Salc    };
7772358Smarkm
7884679Sjhb    private static final class Uint8ArrayData extends TypedArrayData<ByteBuffer> {
7984679Sjhb
8084679Sjhb        private static final MethodHandle GET_ELEM = specialCall(MethodHandles.lookup(), Uint8ArrayData.class, "getElem", int.class, int.class).methodHandle();
8184679Sjhb        private static final MethodHandle SET_ELEM = specialCall(MethodHandles.lookup(), Uint8ArrayData.class, "setElem", void.class, int.class, int.class).methodHandle();
8284679Sjhb
8365514Sphk        private Uint8ArrayData(final ByteBuffer nb, final int start, final int end) {
8465514Sphk            super(((ByteBuffer)nb.position(start).limit(end)).slice(), end - start);
8572358Smarkm        }
8648797Salc
8772358Smarkm        @Override
8884679Sjhb        protected MethodHandle getGetElem() {
8948797Salc            return GET_ELEM;
9084679Sjhb        }
9138517Sdfr
9272358Smarkm        @Override
9348797Salc        protected MethodHandle getSetElem() {
9448797Salc            return SET_ELEM;
9548797Salc        }
9648797Salc
9748797Salc        private int getElem(final int index) {
9848797Salc            try {
9949043Salc                return nb.get(index) & 0xff;
10048797Salc            } catch (final IndexOutOfBoundsException e) {
10148797Salc                throw new ClassCastException(); //force relink - this works for unoptimistic too
10249043Salc            }
10349043Salc        }
10448797Salc
10551938Speter        private void setElem(final int index, final int elem) {
10665514Sphk            try {
10765514Sphk                nb.put(index, (byte)elem);
10865514Sphk            } catch (final IndexOutOfBoundsException e) {
10965514Sphk                //swallow valid array indexes. it's ok.
11065514Sphk                if (index < 0) {
11165514Sphk                    throw new ClassCastException();
11265514Sphk                }
11365514Sphk            }
11465514Sphk        }
11565514Sphk
11665514Sphk        @Override
11765514Sphk        public boolean isUnsigned() {
11865514Sphk            return true;
11965514Sphk        }
12065514Sphk
12165514Sphk        @Override
12265514Sphk        public Class<?> getElementType() {
12365514Sphk            return int.class;
12465514Sphk        }
12565514Sphk
12665514Sphk        @Override
12765514Sphk        public int getInt(final int index) {
12865514Sphk            return getElem(index);
12965514Sphk        }
13065514Sphk
13165514Sphk        @Override
13265514Sphk        public int getIntOptimistic(final int index, final int programPoint) {
13365514Sphk            return getElem(index);
13465514Sphk        }
13565514Sphk
13665514Sphk        @Override
13765514Sphk        public long getLong(final int index) {
13865514Sphk            return getInt(index);
13965514Sphk        }
14065514Sphk
14165514Sphk        @Override
14265514Sphk        public long getLongOptimistic(final int index, final int programPoint) {
14365514Sphk            return getElem(index);
14465514Sphk        }
14565514Sphk
14665514Sphk        @Override
14765514Sphk        public double getDouble(final int index) {
14865514Sphk            return getInt(index);
14965514Sphk        }
15065514Sphk
15165514Sphk        @Override
15265514Sphk        public double getDoubleOptimistic(final int index, final int programPoint) {
15365514Sphk            return getElem(index);
15465514Sphk        }
15565514Sphk
15665514Sphk        @Override
15765514Sphk        public Object getObject(final int index) {
15865514Sphk            return getInt(index);
15965514Sphk        }
16065514Sphk
16165514Sphk        @Override
16271023Sjhb        public ArrayData set(final int index, final Object value, final boolean strict) {
16367351Sjhb            return set(index, JSType.toInt32(value), strict);
16467351Sjhb        }
16571023Sjhb
16671023Sjhb        @Override
16771023Sjhb        public ArrayData set(final int index, final int value, final boolean strict) {
16867351Sjhb            setElem(index, value);
16971023Sjhb            return this;
17067351Sjhb        }
17167351Sjhb
17267351Sjhb        @Override
17367351Sjhb        public ArrayData set(final int index, final long value, final boolean strict) {
17467351Sjhb            return set(index, (int)value, strict);
17567351Sjhb        }
17667351Sjhb
17767351Sjhb        @Override
17867351Sjhb        public ArrayData set(final int index, final double value, final boolean strict) {
17967351Sjhb            return set(index, (int)value, strict);
18067351Sjhb        }
18167351Sjhb
18271023Sjhb    }
18367351Sjhb
18471023Sjhb    /**
18571023Sjhb     * Constructor
18671023Sjhb     *
18771023Sjhb     * @param newObj is this typed array instantiated with the new operator
18871023Sjhb     * @param self   self reference
18971023Sjhb     * @param args   args
19071023Sjhb     *
19171141Sjhb     * @return new typed array
19271023Sjhb     */
19371141Sjhb    @Constructor(arity = 1)
19471023Sjhb    public static NativeUint8Array constructor(final boolean newObj, final Object self, final Object... args) {
19571023Sjhb        return (NativeUint8Array)constructorImpl(newObj, args, FACTORY);
19671023Sjhb    }
19771023Sjhb
19871023Sjhb    NativeUint8Array(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
19971023Sjhb        super(buffer, byteOffset, length);
20071023Sjhb    }
20171023Sjhb
20271023Sjhb    @Override
20371023Sjhb    protected Factory factory() {
20471023Sjhb        return FACTORY;
20571023Sjhb    }
20671023Sjhb
20771023Sjhb    /**
20871023Sjhb     * Set values
20971023Sjhb     * @param self   self reference
21072358Smarkm     * @param array  multiple values of array's type to set
21171085Sjhb     * @param offset optional start index, interpreted  0 if undefined
21267351Sjhb     * @return undefined
21372358Smarkm     */
21471085Sjhb    @Function(attributes = Attribute.NOT_ENUMERABLE)
21571085Sjhb    protected static Object set(final Object self, final Object array, final Object offset) {
21671085Sjhb        return ArrayBufferView.setImpl(self, array, offset);
21771085Sjhb    }
21871085Sjhb
21971085Sjhb    /**
22071085Sjhb     * Returns a new TypedArray view of the ArrayBuffer store for this TypedArray,
22171085Sjhb     * referencing the elements at begin, inclusive, up to end, exclusive. If either
22271085Sjhb     * begin or end is negative, it refers to an index from the end of the array,
22371085Sjhb     * as opposed to from the beginning.
22471085Sjhb     * <p>
22571085Sjhb     * If end is unspecified, the subarray contains all elements from begin to the end
22671085Sjhb     * of the TypedArray. The range specified by the begin and end values is clamped to
22771085Sjhb     * the valid index range for the current array. If the computed length of the new
22871085Sjhb     * TypedArray would be negative, it is clamped to zero.
22971085Sjhb     * <p>
23071085Sjhb     * The returned TypedArray will be of the same type as the array on which this
23171085Sjhb     * method is invoked.
23271085Sjhb     *
23371085Sjhb     * @param self self reference
23471023Sjhb     * @param begin begin position
23571023Sjhb     * @param end end position
23671023Sjhb     *
23771023Sjhb     * @return sub array
23871023Sjhb     */
23971085Sjhb    @Function(attributes = Attribute.NOT_ENUMERABLE)
24067351Sjhb    protected static NativeUint8Array subarray(final Object self, final Object begin, final Object end) {
24167351Sjhb        return (NativeUint8Array)ArrayBufferView.subarrayImpl(self, begin, end);
24271085Sjhb    }
24371085Sjhb
24471085Sjhb    @Override
24571085Sjhb    protected ScriptObject getPrototype(final Global global) {
24671085Sjhb        return global.getUint8ArrayPrototype();
24771085Sjhb    }
24871085Sjhb}
24971085Sjhb