[jffi-next] 22/49: Allow native functions to be called using a CallContext and a function address instead of a Function object

Tim Potter tpot-guest at moszumanska.debian.org
Wed Mar 4 04:51:11 UTC 2015


This is an automated email from the git hooks/post-receive script.

tpot-guest pushed a commit to annotated tag upstream/1.0.10
in repository jffi-next.

commit 2800654f9c6192667e1727f5bc402f5ab8c73312
Author: Wayne Meissner <wmeissner at gmail.com>
Date:   Thu Mar 3 17:27:36 2011 +1000

    Allow native functions to be called using a CallContext and a function address instead of a Function object
---
 src/com/kenai/jffi/CallContext.java |  10 +-
 src/com/kenai/jffi/Invoker.java     | 253 ++++++++++++++++++++++++++++++++++--
 2 files changed, 250 insertions(+), 13 deletions(-)

diff --git a/src/com/kenai/jffi/CallContext.java b/src/com/kenai/jffi/CallContext.java
index 55cb172..03220f3 100644
--- a/src/com/kenai/jffi/CallContext.java
+++ b/src/com/kenai/jffi/CallContext.java
@@ -55,10 +55,14 @@ public final class CallContext implements CallInfo {
     private final int rawParameterSize;
 
     /** The return type of this function */
-    private final Type returnType;
+    final Type returnType;
 
     /** The parameter types of this function */
-    private final Type[] parameterTypes;
+    final Type[] parameterTypes;
+    
+    final long[] parameterTypeHandles;
+    
+    final int flags;
 
     /** A handle to the foreign interface to keep it alive as long as this object is alive */
     private final Foreign foreign = Foreign.getInstance();
@@ -119,6 +123,8 @@ public final class CallContext implements CallInfo {
 
         this.parameterCount = paramTypes.length;
         this.rawParameterSize = foreign.getFunctionRawParameterSize(h);
+        this.parameterTypeHandles = Type.nativeHandles(paramTypes);
+        this.flags = flags;
     }
 
     /**
diff --git a/src/com/kenai/jffi/Invoker.java b/src/com/kenai/jffi/Invoker.java
index c9dc1d5..093339a 100644
--- a/src/com/kenai/jffi/Invoker.java
+++ b/src/com/kenai/jffi/Invoker.java
@@ -72,7 +72,7 @@ public abstract class Invoker {
     public final int invokeVrI(Function function) {
         return foreign.invokeVrI(function.getContextAddress());
     }
-
+    
     /**
      * Invokes a function with no arguments, and returns a 32 bit float.
      *
@@ -82,7 +82,7 @@ public abstract class Invoker {
     public final float invokeVrF(Function function) {
         return foreign.invokeVrF(function.getContextAddress());
     }
-
+    
     /**
      * Invokes a function with no arguments, and returns a 32 bit integer.
      *
@@ -94,7 +94,7 @@ public abstract class Invoker {
     public final int invokeNoErrnoVrI(Function function) {
         return foreign.invokeNoErrnoVrI(function.getContextAddress());
     }
-
+    
     /**
      * Invokes a function with one integer argument, and returns a 32 bit integer.
      *
@@ -105,7 +105,7 @@ public abstract class Invoker {
     public final int invokeIrI(Function function, int arg1) {
         return foreign.invokeIrI(function.getContextAddress(), arg1);
     }
-
+    
     /**
      * Invokes a function with one integer argument, and returns a 32 bit integer.
      *
@@ -118,7 +118,7 @@ public abstract class Invoker {
     public final int invokeNoErrnoIrI(Function function, int arg1) {
         return foreign.invokeNoErrnoIrI(function.getContextAddress(), arg1);
     }
-
+    
     /**
      * Invokes a function with one integer argument, and returns a 32 bit float.
      *
@@ -129,7 +129,7 @@ public abstract class Invoker {
     public final float invokeIrF(Function function, int arg1) {
         return foreign.invokeIrF(function.getContextAddress(), arg1);
     }
-
+    
     /**
      * Invokes a function with two integer arguments, and returns a 32 bit integer.
      *
@@ -141,7 +141,7 @@ public abstract class Invoker {
     public final int invokeIIrI(Function function, int arg1, int arg2) {
         return foreign.invokeIIrI(function.getContextAddress(), arg1, arg2);
     }
-
+    
     /**
      * Invokes a function with two integer arguments, and returns a 32 bit integer.
      *
@@ -155,7 +155,7 @@ public abstract class Invoker {
     public final int invokeNoErrnoIIrI(Function function, int arg1, int arg2) {
         return foreign.invokeNoErrnoIIrI(function.getContextAddress(), arg1, arg2);
     }
-
+    
     /**
      * Invokes a function with two integer arguments, and returns a 32 bit float.
      *
@@ -399,6 +399,16 @@ public abstract class Invoker {
      * @return A native memory address.
      */
     public abstract long invokeAddress(Function function, HeapInvocationBuffer buffer);
+    
+    /**
+     * Invokes a function and returns a native memory address.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @return A native memory address.
+     */
+    public abstract long invokeAddress(CallContext ctx, long function, HeapInvocationBuffer buffer);
 
     /**
      * Invokes a function and returns a 32 bit integer value.
@@ -413,6 +423,26 @@ public abstract class Invoker {
                 ? invokeArrayWithObjectsInt32(function, buffer, objectBuffer)
                 : foreign.invokeArrayReturnInt(function.getContextAddress(), buffer.array());
     }
+    
+    /**
+     * Invokes a function and returns a 32 bit integer value.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @return A native memory address.
+     */
+    public final int invokeInt(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+        ObjectBuffer objectBuffer = buffer.objectBuffer();
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            return objectBuffer != null
+                ? invokeArrayWithObjectsInt32(fnHandle, buffer, objectBuffer)
+                : foreign.invokeArrayReturnInt(fnHandle, buffer.array());
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
 
     /**
      * Invokes a function and returns a 64 bit integer value.
@@ -427,6 +457,26 @@ public abstract class Invoker {
                 ? foreign.invokeArrayWithObjectsInt64(function.getContextAddress(), buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects())
                 : foreign.invokeArrayReturnLong(function.getContextAddress(), buffer.array());
     }
+    
+    /**
+     * Invokes a function and returns a 64 bit integer value.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @return A native memory address.
+     */
+    public final long invokeLong(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+        ObjectBuffer objectBuffer = buffer.objectBuffer();
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            return objectBuffer != null
+                ? invokeArrayWithObjectsInt64(fnHandle, buffer, objectBuffer)
+                : foreign.invokeArrayReturnLong(fnHandle, buffer.array());
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
 
     /**
      * Invokes a function and returns a 32 bit floating point value.
@@ -441,6 +491,27 @@ public abstract class Invoker {
                 ? foreign.invokeArrayWithObjectsFloat(function.getContextAddress(), buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects())
                 : foreign.invokeArrayReturnFloat(function.getContextAddress(), buffer.array());
     }
+    
+    /**
+     * Invokes a function and returns a 32 bit floating point value.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @return A native memory address.
+     */
+    public final float invokeFloat(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+        ObjectBuffer objectBuffer = buffer.objectBuffer();
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            return objectBuffer != null
+                ? foreign.invokeArrayWithObjectsFloat(fnHandle, buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects())
+                : foreign.invokeArrayReturnFloat(fnHandle, buffer.array());
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
+    
 
     /**
      * Invokes a function and returns a 64 bit floating point value.
@@ -455,6 +526,26 @@ public abstract class Invoker {
                 ? foreign.invokeArrayWithObjectsDouble(function.getContextAddress(), buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects())
                 : foreign.invokeArrayReturnDouble(function.getContextAddress(), buffer.array());
     }
+    
+    /**
+     * Invokes a function and returns a 64 bit floating point value.
+     *
+     * @param ctx The call context describing how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @return A native memory address.
+     */
+    public final double invokeDouble(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+        ObjectBuffer objectBuffer = buffer.objectBuffer();
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            return objectBuffer != null
+                ? foreign.invokeArrayWithObjectsDouble(fnHandle, buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects())
+                : foreign.invokeArrayReturnDouble(fnHandle, buffer.array());
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
 
     /**
      * Invokes a function that returns a C struct by value.
@@ -470,6 +561,21 @@ public abstract class Invoker {
 
         return returnBuffer;
     }
+    
+    /**
+     * Invokes a function that returns a C struct by value.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer The parameter buffer.
+     * @return A byte array with the return value encoded in native byte order.
+     */
+    public final byte[] invokeStruct(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+        byte[] returnBuffer = new byte[ctx.getReturnType().size()];
+        invokeStruct(ctx, function, buffer, returnBuffer, 0);
+
+        return returnBuffer;
+    }
 
     /**
      * Invokes a function that returns a C struct by value.
@@ -489,6 +595,31 @@ public abstract class Invoker {
             foreign.invokeArrayReturnStruct(function.getContextAddress(), buffer.array(), returnBuffer, offset);
         }
     }
+    
+    /**
+     * Invokes a function that returns a C struct by value.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer The parameter buffer.
+     * @param returnBuffer The output buffer to place the return value in.
+     * @param offset The offset within returnBuffer to place the return value.
+     */
+    public final void invokeStruct(CallContext ctx, long function, HeapInvocationBuffer buffer, byte[] returnBuffer, int offset) {
+        ObjectBuffer objectBuffer = buffer.objectBuffer();
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            if (objectBuffer != null) {
+                foreign.invokeArrayWithObjectsReturnStruct(fnHandle,
+                        buffer.array(), objectBuffer.objectCount(), objectBuffer.info(), objectBuffer.objects(),
+                        returnBuffer, offset);
+            } else {
+                foreign.invokeArrayReturnStruct(fnHandle, buffer.array(), returnBuffer, offset);
+            }
+        } finally { 
+            foreign.freeFunction(fnHandle);
+        }
+    }
 
     public final Object invokeObject(Function function, HeapInvocationBuffer buffer) {
         ObjectBuffer objectBuffer = buffer.objectBuffer();
@@ -508,6 +639,25 @@ public abstract class Invoker {
     public final void invoke(Function function, long returnBuffer, long[] parameters) {
         foreign.invokePointerParameterArray(function.getContextAddress(), returnBuffer, parameters);
     }
+    
+    /**
+     * Invokes a function, with the parameters loaded into native memory buffers,
+     * and the function result is stored in a native memory buffer.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param returnBuffer The address of the native buffer to place the result
+     * of the function call in.
+     * @param parameters An array of addresses of the function parameters.
+     */
+    public final void invoke(CallContext ctx, long function, long returnBuffer, long[] parameters) {
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            foreign.invokePointerParameterArray(fnHandle, returnBuffer, parameters);
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
 
     /**
      * Convenience method to pass the objects and object descriptor array down as
@@ -521,24 +671,97 @@ public abstract class Invoker {
      */
     private final int invokeArrayWithObjectsInt32(Function function, HeapInvocationBuffer buffer,
             ObjectBuffer objectBuffer) {
+        return invokeArrayWithObjectsInt32(function.getContextAddress(), buffer, objectBuffer);
+    }
+    
+    /**
+     * Convenience method to pass the objects and object descriptor array down as
+     * normal arguments, so hotspot can optimize it.  This is faster than the native
+     * code pulling the objects and descriptors out of arrays.
+     *
+     * @param ctx The call context which describes how to call the native function.
+     * @param function The address of the native function to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @param objectBuffer A buffer containing objects to be passed to the native function.
+     * @return A 32 bit integer value.
+     */
+    private final int invokeArrayWithObjectsInt32(CallContext ctx, long function, HeapInvocationBuffer buffer,
+            ObjectBuffer objectBuffer) {
+        final long fnHandle = newFunction(ctx, function);
+        try {
+            return invokeArrayWithObjectsInt32(fnHandle, buffer, objectBuffer);
+        } finally {
+            foreign.freeFunction(fnHandle);
+        }
+    }
+    
+    /**
+     * Convenience method to pass the objects and object descriptor array down as
+     * normal arguments, so hotspot can optimize it.  This is faster than the native
+     * code pulling the objects and descriptors out of arrays.
+     *
+     * @param fnHandle The native function handle to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @param objectBuffer A buffer containing objects to be passed to the native function.
+     * @return A 32 bit integer value.
+     */
+    private final int invokeArrayWithObjectsInt32(long fnHandle, HeapInvocationBuffer buffer,
+            ObjectBuffer objectBuffer) {
+
         Object[] objects = objectBuffer.objects();
         int[] info = objectBuffer.info();
         int objectCount = objectBuffer.objectCount();
 
         switch (objectCount) {
             case 1:
-                return foreign.invokeArrayO1Int32(function.getContextAddress(), buffer.array(),
+                return foreign.invokeArrayO1Int32(fnHandle, buffer.array(),
                         objects[0], info[0], info[1], info[2]);
             case 2:
-                return foreign.invokeArrayO2Int32(function.getContextAddress(), buffer.array(),
+                return foreign.invokeArrayO2Int32(fnHandle, buffer.array(),
                         objects[0], info[0], info[1], info[2],
                         objects[1], info[3], info[4], info[5]);
         }
 
-        return foreign.invokeArrayWithObjectsInt32(function.getContextAddress(), buffer.array(),
+        return foreign.invokeArrayWithObjectsInt32(fnHandle, buffer.array(),
             objectCount, info, objects);
     }
+    
+    /**
+     * Convenience method to pass the objects and object descriptor array down as
+     * normal arguments, so hotspot can optimize it.  This is faster than the native
+     * code pulling the objects and descriptors out of arrays.
+     *
+     * @param fnHandle The native function handle to invoke.
+     * @param buffer A buffer containing the arguments to the function.
+     * @param objectBuffer A buffer containing objects to be passed to the native function.
+     * @return A 64 bit integer value.
+     */
+    private final long invokeArrayWithObjectsInt64(long fnHandle, HeapInvocationBuffer buffer,
+            ObjectBuffer objectBuffer) {
+
+        Object[] objects = objectBuffer.objects();
+        int[] info = objectBuffer.info();
+        int objectCount = objectBuffer.objectCount();
+
+        switch (objectCount) {
+            case 1:
+                return foreign.invokeArrayO1Int64(fnHandle, buffer.array(),
+                        objects[0], info[0], info[1], info[2]);
+            case 2:
+                return foreign.invokeArrayO2Int64(fnHandle, buffer.array(),
+                        objects[0], info[0], info[1], info[2],
+                        objects[1], info[3], info[4], info[5]);
+        }
 
+        return foreign.invokeArrayWithObjectsInt64(fnHandle, buffer.array(),
+            objectCount, info, objects);
+    }
+    
+    private long newFunction(CallContext ctx, long function) {
+        return foreign.newFunction(function, ctx.getReturnType().handle(), 
+                ctx.parameterTypeHandles, ctx.flags);
+    }
+    
     /**
      * A 32 bit invoker implementation
      */
@@ -548,6 +771,10 @@ public abstract class Invoker {
         public final long invokeAddress(Function function, HeapInvocationBuffer buffer) {
             return ((long)invokeInt(function, buffer)) & ADDRESS_MASK;
         }
+        
+        public final long invokeAddress(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+            return ((long)invokeInt(ctx, function, buffer)) & ADDRESS_MASK;
+        }
     }
 
 
@@ -560,5 +787,9 @@ public abstract class Invoker {
         public long invokeAddress(Function function, HeapInvocationBuffer buffer) {
             return invokeLong(function, buffer);
         }
+        
+        public final long invokeAddress(CallContext ctx, long function, HeapInvocationBuffer buffer) {
+            return invokeLong(ctx, function, buffer);
+        }
     }
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-java/jffi-next.git



More information about the pkg-java-commits mailing list