package com.oracle.truffle.js.runtime.builtins;
import java.nio.ByteBuffer;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.object.Shape;
import com.oracle.truffle.js.runtime.Errors;
import com.oracle.truffle.js.runtime.JSAgentWaiterList;
import com.oracle.truffle.js.runtime.objects.JSNonProxyObject;
import com.oracle.truffle.js.runtime.util.DirectByteBufferHelper;
public abstract class JSArrayBufferObject extends JSNonProxyObject {
public static final String CLASS_NAME = "ArrayBuffer";
public static final String PROTOTYPE_NAME = CLASS_NAME + ".prototype";
protected JSArrayBufferObject(Shape shape) {
super(shape);
}
@Override
public String getClassName() {
return CLASS_NAME;
}
public abstract void detachArrayBuffer();
public static byte[] getByteArray(DynamicObject thisObj) {
assert JSAbstractBuffer.isJSAbstractHeapBuffer(thisObj);
return ((Heap) thisObj).getByteArray();
}
public static int getByteLength(DynamicObject thisObj) {
assert JSAbstractBuffer.isJSAbstractHeapBuffer(thisObj);
return getByteArray(thisObj).length;
}
public static int getDirectByteLength(DynamicObject thisObj) {
return getDirectByteBuffer(thisObj).capacity();
}
public static void setDirectByteBuffer(DynamicObject thisObj, ByteBuffer buffer) {
((DirectBase) thisObj).setByteBuffer(buffer);
}
public static ByteBuffer getDirectByteBuffer(DynamicObject thisObj) {
assert JSArrayBuffer.isJSDirectArrayBuffer(thisObj) || JSSharedArrayBuffer.isJSSharedArrayBuffer(thisObj);
return DirectByteBufferHelper.cast(((DirectBase) thisObj).getByteBuffer());
}
public static JSAgentWaiterList getWaiterList(DynamicObject thisObj) {
return ((Shared) thisObj).getWaiterList();
}
public static void setWaiterList(DynamicObject thisObj, JSAgentWaiterList waiterList) {
((Shared) thisObj).setWaiterList(waiterList);
}
public static final class Heap extends JSArrayBufferObject {
byte[] byteArray;
protected Heap(Shape shape, byte[] byteArray) {
super(shape);
this.byteArray = byteArray;
}
public byte[] getByteArray() {
return byteArray;
}
@Override
public void detachArrayBuffer() {
this.byteArray = null;
}
}
public abstract static class DirectBase extends JSArrayBufferObject {
ByteBuffer byteBuffer;
protected DirectBase(Shape shape, ByteBuffer byteBuffer) {
super(shape);
this.byteBuffer = byteBuffer;
}
public final ByteBuffer getByteBuffer() {
return byteBuffer;
}
public final void setByteBuffer(ByteBuffer byteBuffer) {
this.byteBuffer = byteBuffer;
}
@Override
public abstract void detachArrayBuffer();
}
public static final class Direct extends DirectBase {
protected Direct(Shape shape, ByteBuffer byteBuffer) {
super(shape, byteBuffer);
}
@Override
public void detachArrayBuffer() {
this.byteBuffer = null;
}
}
public static final class Shared extends DirectBase {
JSAgentWaiterList waiterList;
protected Shared(Shape shape, ByteBuffer byteBuffer, JSAgentWaiterList waiterList) {
super(shape, byteBuffer);
this.waiterList = waiterList;
}
public JSAgentWaiterList getWaiterList() {
return waiterList;
}
public void setWaiterList(JSAgentWaiterList waiterList) {
this.waiterList = waiterList;
}
@Override
public void detachArrayBuffer() {
throw Errors.unsupported("SharedArrayBuffer cannot be detached");
}
}
public static DynamicObject createHeapArrayBuffer(Shape shape, byte[] byteArray) {
return new Heap(shape, byteArray);
}
public static DynamicObject createDirectArrayBuffer(Shape shape, ByteBuffer byteBuffer) {
return new Direct(shape, byteBuffer);
}
public static DynamicObject createSharedArrayBuffer(Shape shape, ByteBuffer byteBuffer, JSAgentWaiterList waiterList) {
return new Shared(shape, byteBuffer, waiterList);
}
}