diff options
Diffstat (limited to 'src/jdk/nashorn/internal/objects/NativeArrayBuffer.java')
-rw-r--r-- | src/jdk/nashorn/internal/objects/NativeArrayBuffer.java | 166 |
1 files changed, 130 insertions, 36 deletions
diff --git a/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java index 70c97daf..e3c5c00d 100644 --- a/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java +++ b/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java @@ -25,27 +25,81 @@ package jdk.nashorn.internal.objects; +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.nio.ByteBuffer; -import java.util.Arrays; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.Getter; import jdk.nashorn.internal.objects.annotations.ScriptClass; +import jdk.nashorn.internal.objects.annotations.SpecializedFunction; +import jdk.nashorn.internal.objects.annotations.Where; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +/** + * NativeArrayBuffer - ArrayBuffer as described in the JS typed + * array spec + */ @ScriptClass("ArrayBuffer") -final class NativeArrayBuffer extends ScriptObject { - private final byte[] buffer; +public final class NativeArrayBuffer extends ScriptObject { + private final ByteBuffer nb; // initialized by nasgen private static PropertyMap $nasgenmap$; + /** + * Constructor + * @param nb native byte buffer to wrap + * @param global global instance + */ + protected NativeArrayBuffer(final ByteBuffer nb, final Global global) { + super(global.getArrayBufferPrototype(), $nasgenmap$); + this.nb = nb; + } + + /** + * Constructor + * @param nb native byte buffer to wrap + */ + protected NativeArrayBuffer(final ByteBuffer nb) { + this(nb, Global.instance()); + } + + /** + * Constructor + * @param byteLength byteLength for buffer + */ + protected NativeArrayBuffer(final int byteLength) { + this(ByteBuffer.allocateDirect(byteLength)); + } + + /** + * Clone constructor + * Used only for slice + * @param other original buffer + * @param begin begin byte index + * @param end end byte index + */ + protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) { + this(cloneBuffer(other.getNioBuffer(), begin, end)); + } + + /** + * Constructor + * @param newObj is this invoked with new + * @param self self reference + * @param args arguments to constructor + * @return new NativeArrayBuffer + */ @Constructor(arity = 1) public static NativeArrayBuffer constructor(final boolean newObj, final Object self, final Object... args) { + if (!newObj) { + throw typeError("constructor.requires.new", "ArrayBuffer"); + } + if (args.length == 0) { throw new RuntimeException("missing length argument"); } @@ -53,21 +107,19 @@ final class NativeArrayBuffer extends ScriptObject { return new NativeArrayBuffer(JSType.toInt32(args[0])); } - protected NativeArrayBuffer(final byte[] byteArray, final Global global) { - super(global.getArrayBufferPrototype(), $nasgenmap$); - this.buffer = byteArray; - } - - protected NativeArrayBuffer(final byte[] byteArray) { - this(byteArray, Global.instance()); + private static ByteBuffer cloneBuffer(final ByteBuffer original, final int begin, final int end) { + final ByteBuffer clone = ByteBuffer.allocateDirect(original.capacity()); + original.rewind();//copy from the beginning + clone.put(original); + original.rewind(); + clone.flip(); + clone.position(begin); + clone.limit(end); + return clone.slice(); } - protected NativeArrayBuffer(final int byteLength) { - this(new byte[byteLength]); - } - - protected NativeArrayBuffer(final NativeArrayBuffer other, final int begin, final int end) { - this(Arrays.copyOfRange(other.buffer, begin, end)); + ByteBuffer getNioBuffer() { + return nb; } @Override @@ -75,19 +127,68 @@ final class NativeArrayBuffer extends ScriptObject { return "ArrayBuffer"; } + /** + * Byte length for native array buffer + * @param self native array buffer + * @return byte length + */ @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE) - public static Object byteLength(final Object self) { - return ((NativeArrayBuffer)self).buffer.length; + public static int byteLength(final Object self) { + return ((NativeArrayBuffer)self).getByteLength(); + } + + /** + * Returns true if an object is an ArrayBufferView + * + * @param self self + * @param obj object to check + * + * @return true if obj is an ArrayBufferView + */ + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) + public static boolean isView(final Object self, final Object obj) { + return obj instanceof ArrayBufferView; } + /** + * Slice function + * @param self native array buffer + * @param begin0 start byte index + * @param end0 end byte index + * @return new array buffer, sliced + */ @Function(attributes = Attribute.NOT_ENUMERABLE) public static NativeArrayBuffer slice(final Object self, final Object begin0, final Object end0) { final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self; - int begin = JSType.toInt32(begin0); - int end = end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : arrayBuffer.getByteLength(); - begin = adjustIndex(begin, arrayBuffer.getByteLength()); - end = adjustIndex(end, arrayBuffer.getByteLength()); - return new NativeArrayBuffer((NativeArrayBuffer) self, begin, Math.max(end, begin)); + final int byteLength = arrayBuffer.getByteLength(); + final int begin = adjustIndex(JSType.toInt32(begin0), byteLength); + final int end = adjustIndex(end0 != ScriptRuntime.UNDEFINED ? JSType.toInt32(end0) : byteLength, byteLength); + return new NativeArrayBuffer(arrayBuffer, begin, Math.max(end, begin)); + } + + /** + * Specialized slice function + * @param self native array buffer + * @param begin start byte index + * @param end end byte index + * @return new array buffer, sliced + */ + @SpecializedFunction + public static Object slice(final Object self, final int begin, final int end) { + final NativeArrayBuffer arrayBuffer = (NativeArrayBuffer)self; + final int byteLength = arrayBuffer.getByteLength(); + return new NativeArrayBuffer(arrayBuffer, adjustIndex(begin, byteLength), Math.max(adjustIndex(end, byteLength), begin)); + } + + /** + * Specialized slice function + * @param self native array buffer + * @param begin start byte index + * @return new array buffer, sliced + */ + @SpecializedFunction + public static Object slice(final Object self, final int begin) { + return slice(self, begin, ((NativeArrayBuffer)self).getByteLength()); } /** @@ -100,10 +201,7 @@ final class NativeArrayBuffer extends ScriptObject { * @return valid index index in the range [0, length). */ static int adjustIndex(final int index, final int length) { - if (index < 0) { - return clamp(index + length, length); - } - return clamp(index, length); + return index < 0 ? clamp(index + length, length) : clamp(index, length); } /** @@ -118,23 +216,19 @@ final class NativeArrayBuffer extends ScriptObject { return index; } - public byte[] getByteArray() { - return buffer; - } - - public int getByteLength() { - return buffer.length; + int getByteLength() { + return nb.limit(); } ByteBuffer getBuffer() { - return ByteBuffer.wrap(buffer); + return nb; } ByteBuffer getBuffer(final int offset) { - return ByteBuffer.wrap(buffer, offset, buffer.length - offset); + return (ByteBuffer)nb.duplicate().position(offset); } ByteBuffer getBuffer(final int offset, final int length) { - return ByteBuffer.wrap(buffer, offset, length); + return (ByteBuffer)getBuffer(offset).limit(length); } } |