--- old/src/sample/nashorn/dynalink/BufferIndexingLinkerExporter.java 2020-04-15 18:53:10.000000000 +0530 +++ /dev/null 2020-04-15 18:53:10.000000000 +0530 @@ -1,249 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * - Neither the name of Oracle nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS - * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -import static jdk.dynalink.StandardNamespace.ELEMENT; -import static jdk.dynalink.StandardNamespace.PROPERTY; -import static jdk.dynalink.StandardOperation.GET; -import static jdk.dynalink.StandardOperation.SET; - -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.nio.Buffer; -import java.nio.ByteBuffer; -import java.nio.CharBuffer; -import java.nio.DoubleBuffer; -import java.nio.FloatBuffer; -import java.nio.IntBuffer; -import java.nio.LongBuffer; -import java.nio.ShortBuffer; -import java.util.ArrayList; -import java.util.List; -import jdk.dynalink.CallSiteDescriptor; -import jdk.dynalink.NamedOperation; -import jdk.dynalink.NamespaceOperation; -import jdk.dynalink.Operation; -import jdk.dynalink.StandardNamespace; -import jdk.dynalink.linker.GuardedInvocation; -import jdk.dynalink.linker.GuardingDynamicLinker; -import jdk.dynalink.linker.GuardingDynamicLinkerExporter; -import jdk.dynalink.linker.LinkRequest; -import jdk.dynalink.linker.LinkerServices; -import jdk.dynalink.linker.TypeBasedGuardingDynamicLinker; -import jdk.dynalink.linker.support.Guards; -import jdk.dynalink.linker.support.Lookup; - -/** - * This is a dynalink pluggable linker (see http://openjdk.java.net/jeps/276). - * This linker adds array-like indexing and "length" property to nio Buffer objects. - */ -public final class BufferIndexingLinkerExporter extends GuardingDynamicLinkerExporter { - static { - System.out.println("pluggable dynalink buffer indexing linker loaded"); - } - - private static final MethodHandle BUFFER_LIMIT; - private static final MethodHandle BYTEBUFFER_GET; - private static final MethodHandle BYTEBUFFER_PUT; - private static final MethodHandle CHARBUFFER_GET; - private static final MethodHandle CHARBUFFER_PUT; - private static final MethodHandle SHORTBUFFER_GET; - private static final MethodHandle SHORTBUFFER_PUT; - private static final MethodHandle INTBUFFER_GET; - private static final MethodHandle INTBUFFER_PUT; - private static final MethodHandle LONGBUFFER_GET; - private static final MethodHandle LONGBUFFER_PUT; - private static final MethodHandle FLOATBUFFER_GET; - private static final MethodHandle FLOATBUFFER_PUT; - private static final MethodHandle DOUBLEBUFFER_GET; - private static final MethodHandle DOUBLEBUFFER_PUT; - - // guards - private static final MethodHandle IS_BUFFER; - private static final MethodHandle IS_BYTEBUFFER; - private static final MethodHandle IS_CHARBUFFER; - private static final MethodHandle IS_SHORTBUFFER; - private static final MethodHandle IS_INTBUFFER; - private static final MethodHandle IS_LONGBUFFER; - private static final MethodHandle IS_FLOATBUFFER; - private static final MethodHandle IS_DOUBLEBUFFER; - - private static final MethodType GUARD_TYPE; - - static { - final Lookup look = Lookup.PUBLIC; - BUFFER_LIMIT = look.findVirtual(Buffer.class, "limit", MethodType.methodType(int.class)); - BYTEBUFFER_GET = look.findVirtual(ByteBuffer.class, "get", - MethodType.methodType(byte.class, int.class)); - BYTEBUFFER_PUT = look.findVirtual(ByteBuffer.class, "put", - MethodType.methodType(ByteBuffer.class, int.class, byte.class)); - CHARBUFFER_GET = look.findVirtual(CharBuffer.class, "get", - MethodType.methodType(char.class, int.class)); - CHARBUFFER_PUT = look.findVirtual(CharBuffer.class, "put", - MethodType.methodType(CharBuffer.class, int.class, char.class)); - SHORTBUFFER_GET = look.findVirtual(ShortBuffer.class, "get", - MethodType.methodType(short.class, int.class)); - SHORTBUFFER_PUT = look.findVirtual(ShortBuffer.class, "put", - MethodType.methodType(ShortBuffer.class, int.class, short.class)); - INTBUFFER_GET = look.findVirtual(IntBuffer.class, "get", - MethodType.methodType(int.class, int.class)); - INTBUFFER_PUT = look.findVirtual(IntBuffer.class, "put", - MethodType.methodType(IntBuffer.class, int.class, int.class)); - LONGBUFFER_GET = look.findVirtual(LongBuffer.class, "get", - MethodType.methodType(long.class, int.class)); - LONGBUFFER_PUT = look.findVirtual(LongBuffer.class, "put", - MethodType.methodType(LongBuffer.class, int.class, long.class)); - FLOATBUFFER_GET = look.findVirtual(FloatBuffer.class, "get", - MethodType.methodType(float.class, int.class)); - FLOATBUFFER_PUT = look.findVirtual(FloatBuffer.class, "put", - MethodType.methodType(FloatBuffer.class, int.class, float.class)); - DOUBLEBUFFER_GET = look.findVirtual(DoubleBuffer.class, "get", - MethodType.methodType(double.class, int.class)); - DOUBLEBUFFER_PUT = look.findVirtual(DoubleBuffer.class, "put", - MethodType.methodType(DoubleBuffer.class, int.class, double.class)); - - GUARD_TYPE = MethodType.methodType(boolean.class, Object.class); - IS_BUFFER = Guards.isInstance(Buffer.class, GUARD_TYPE); - IS_BYTEBUFFER = Guards.isInstance(ByteBuffer.class, GUARD_TYPE); - IS_CHARBUFFER = Guards.isInstance(CharBuffer.class, GUARD_TYPE); - IS_SHORTBUFFER = Guards.isInstance(ShortBuffer.class, GUARD_TYPE); - IS_INTBUFFER = Guards.isInstance(IntBuffer.class, GUARD_TYPE); - IS_LONGBUFFER = Guards.isInstance(LongBuffer.class, GUARD_TYPE); - IS_FLOATBUFFER = Guards.isInstance(FloatBuffer.class, GUARD_TYPE); - IS_DOUBLEBUFFER = Guards.isInstance(DoubleBuffer.class, GUARD_TYPE); - } - - @Override - public List get() { - final ArrayList linkers = new ArrayList<>(); - linkers.add(new TypeBasedGuardingDynamicLinker() { - @Override - public boolean canLinkType(final Class type) { - return Buffer.class.isAssignableFrom(type); - } - - @Override - public GuardedInvocation getGuardedInvocation(final LinkRequest request, - final LinkerServices linkerServices) throws Exception { - final Object self = request.getReceiver(); - if (self == null || !canLinkType(self.getClass())) { - return null; - } - - final CallSiteDescriptor desc = request.getCallSiteDescriptor(); - final Operation namedOp = desc.getOperation(); - final Operation namespaceOp = NamedOperation.getBaseOperation(namedOp); - final Operation op = NamespaceOperation.getBaseOperation(namespaceOp); - final StandardNamespace ns = StandardNamespace.findFirst(namespaceOp); - if (ns == null) { - return null; - } - - if (op == GET) { - if (ns == ELEMENT) { - return linkGetElement(self); - } else if (ns == PROPERTY) { - final Object name = NamedOperation.getName(desc.getOperation()); - if ("length".equals(name)) { - return linkLength(); - } - } - } else if (op == SET && ns == ELEMENT) { - return linkSetElement(self); - } - - return null; - } - }); - return linkers; - } - - private static GuardedInvocation linkGetElement(final Object self) { - MethodHandle method = null; - MethodHandle guard = null; - if (self instanceof ByteBuffer) { - method = BYTEBUFFER_GET; - guard = IS_BYTEBUFFER; - } else if (self instanceof CharBuffer) { - method = CHARBUFFER_GET; - guard = IS_CHARBUFFER; - } else if (self instanceof ShortBuffer) { - method = SHORTBUFFER_GET; - guard = IS_SHORTBUFFER; - } else if (self instanceof IntBuffer) { - method = INTBUFFER_GET; - guard = IS_INTBUFFER; - } else if (self instanceof LongBuffer) { - method = LONGBUFFER_GET; - guard = IS_LONGBUFFER; - } else if (self instanceof FloatBuffer) { - method = FLOATBUFFER_GET; - guard = IS_FLOATBUFFER; - } else if (self instanceof DoubleBuffer) { - method = DOUBLEBUFFER_GET; - guard = IS_DOUBLEBUFFER; - } - - return method != null? new GuardedInvocation(method, guard) : null; - } - - private static GuardedInvocation linkSetElement(final Object self) { - MethodHandle method = null; - MethodHandle guard = null; - if (self instanceof ByteBuffer) { - method = BYTEBUFFER_PUT; - guard = IS_BYTEBUFFER; - } else if (self instanceof CharBuffer) { - method = CHARBUFFER_PUT; - guard = IS_CHARBUFFER; - } else if (self instanceof ShortBuffer) { - method = SHORTBUFFER_PUT; - guard = IS_SHORTBUFFER; - } else if (self instanceof IntBuffer) { - method = INTBUFFER_PUT; - guard = IS_INTBUFFER; - } else if (self instanceof LongBuffer) { - method = LONGBUFFER_PUT; - guard = IS_LONGBUFFER; - } else if (self instanceof FloatBuffer) { - method = FLOATBUFFER_PUT; - guard = IS_FLOATBUFFER; - } else if (self instanceof DoubleBuffer) { - method = DOUBLEBUFFER_PUT; - guard = IS_DOUBLEBUFFER; - } - - return method != null? new GuardedInvocation(method, guard) : null; - } - - private static GuardedInvocation linkLength() { - return new GuardedInvocation(BUFFER_LIMIT, IS_BUFFER); - } -}