src.org.python.modules.jffi.DefaultInvokerFactory Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jython-standalone Show documentation
Show all versions of jython-standalone Show documentation
Jython is an implementation of the high-level, dynamic, object-oriented
language Python written in 100% Pure Java, and seamlessly integrated with
the Java platform. It thus allows you to run Python on any Java platform.
package org.python.modules.jffi;
import com.kenai.jffi.ArrayFlags;
import com.kenai.jffi.Function;
import com.kenai.jffi.HeapInvocationBuffer;
import com.kenai.jffi.Platform;
import org.python.core.Py;
import org.python.core.PyNone;
import org.python.core.PyObject;
class DefaultInvokerFactory {
private static final class SingletonHolder {
public static final DefaultInvokerFactory INSTANCE = new DefaultInvokerFactory();
}
public static final DefaultInvokerFactory getFactory() {
return SingletonHolder.INSTANCE;
}
private DefaultInvokerFactory() {}
final Invoker createInvoker(com.kenai.jffi.Function function, PyObject returnType, PyObject[] parameterTypes) {
ParameterMarshaller[] marshallers = new ParameterMarshaller[parameterTypes.length];
for (int i = 0; i < marshallers.length; ++i) {
marshallers[i] = getMarshaller(parameterTypes[i]);
}
return createInvoker(function, returnType, marshallers);
}
final Invoker createInvoker(com.kenai.jffi.Function function, CType[] parameterTypes, CType returnType) {
ParameterMarshaller[] marshallers = new ParameterMarshaller[parameterTypes.length];
for (int i = 0; i < marshallers.length; ++i) {
marshallers[i] = getMarshaller(parameterTypes[i]);
}
return createInvoker(function, returnType, marshallers);
}
final Invoker createInvoker(com.kenai.jffi.Function function, NativeType[] parameterTypes, NativeType returnType) {
ParameterMarshaller[] marshallers = new ParameterMarshaller[parameterTypes.length];
for (int i = 0; i < marshallers.length; ++i) {
marshallers[i] = getMarshaller(parameterTypes[i]);
}
return createInvoker(function, returnType, marshallers);
}
final Invoker createInvoker(com.kenai.jffi.Function function, PyObject returnType, ParameterMarshaller[] marshallers) {
CType cReturnType = CType.typeOf(returnType);
if (cReturnType instanceof CType.Builtin) {
return createInvoker(function, cReturnType.getNativeType(), marshallers);
}
throw Py.RuntimeError("Unsupported return type: " + returnType);
}
final Invoker createInvoker(com.kenai.jffi.Function function, NativeType returnType, ParameterMarshaller[] marshallers) {
switch (returnType) {
case VOID:
return new VoidInvoker(function, marshallers);
case BYTE:
return new Signed8Invoker(function, marshallers);
case UBYTE:
return new Unsigned8Invoker(function, marshallers);
case SHORT:
return new Signed16Invoker(function, marshallers);
case USHORT:
return new Unsigned16Invoker(function, marshallers);
case INT:
return new Signed32Invoker(function, marshallers);
case UINT:
return new Unsigned32Invoker(function, marshallers);
case LONGLONG:
return new Signed64Invoker(function, marshallers);
case ULONGLONG:
return new Unsigned64Invoker(function, marshallers);
case LONG:
return Platform.getPlatform().longSize() == 32
? new Signed32Invoker(function, marshallers)
: new Signed64Invoker(function, marshallers);
case ULONG:
return Platform.getPlatform().longSize() == 32
? new Unsigned32Invoker(function, marshallers)
: new Unsigned64Invoker(function, marshallers);
case FLOAT:
return new FloatInvoker(function, marshallers);
case DOUBLE:
return new DoubleInvoker(function, marshallers);
case POINTER:
return new PointerInvoker(function, marshallers);
case STRING:
return new StringInvoker(function, marshallers);
default:
break;
}
throw Py.RuntimeError("Unsupported return type: " + returnType);
}
static final ParameterMarshaller getMarshaller(NativeType type) {
switch (type) {
case BYTE:
return Signed8Marshaller.INSTANCE;
case UBYTE:
return Unsigned8Marshaller.INSTANCE;
case SHORT:
return Signed16Marshaller.INSTANCE;
case USHORT:
return Unsigned16Marshaller.INSTANCE;
case INT:
return Signed32Marshaller.INSTANCE;
case UINT:
return Unsigned32Marshaller.INSTANCE;
case LONGLONG:
return Signed64Marshaller.INSTANCE;
case ULONGLONG:
return Unsigned64Marshaller.INSTANCE;
case LONG:
return Platform.getPlatform().longSize() == 32
? Signed32Marshaller.INSTANCE : Signed64Marshaller.INSTANCE;
case ULONG:
return Platform.getPlatform().longSize() == 32
? Unsigned32Marshaller.INSTANCE : Unsigned64Marshaller.INSTANCE;
case FLOAT:
return FloatMarshaller.INSTANCE;
case DOUBLE:
return DoubleMarshaller.INSTANCE;
case POINTER:
return PointerMarshaller.INSTANCE;
case STRING:
return StringMarshaller.INSTANCE;
default:
throw Py.RuntimeError("Unsupported parameter type: " + type);
}
}
static final ParameterMarshaller getMarshaller(CType type) {
if (type instanceof CType.Builtin) {
return getMarshaller(type.getNativeType());
} else if (type instanceof CType.Pointer) {
return PointerMarshaller.INSTANCE;
} else {
throw Py.RuntimeError("Unsupported parameter type: " + type);
}
}
static final ParameterMarshaller getMarshaller(PyObject type) {
return getMarshaller(CType.typeOf(type));
}
static interface ParameterMarshaller {
void marshal(HeapInvocationBuffer buffer, PyObject arg);
}
private static abstract class BaseInvoker extends Invoker {
final Function jffiFunction;
final com.kenai.jffi.Invoker jffiInvoker = com.kenai.jffi.Invoker.getInstance();
final ParameterMarshaller[] marshallers;
final int arity;
public BaseInvoker(Function function, ParameterMarshaller[] marshallers) {
this.jffiFunction= function;
this.marshallers = marshallers;
this.arity = marshallers.length;
}
final HeapInvocationBuffer convertArguments(PyObject[] args) {
checkArity(args);
HeapInvocationBuffer buffer = new HeapInvocationBuffer(jffiFunction);
for (int i = 0; i < marshallers.length; ++i) {
marshallers[i].marshal(buffer, args[i]);
}
return buffer;
}
public final PyObject invoke() {
return invoke(new PyObject[0]);
}
public final PyObject invoke(PyObject arg0) {
return invoke(new PyObject[] { arg0 });
}
public final PyObject invoke(PyObject arg0, PyObject arg1) {
return invoke(new PyObject[] { arg0, arg1 });
}
public final PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2) {
return invoke(new PyObject[] { arg0, arg1, arg2 });
}
public final PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3) {
return invoke(new PyObject[] { arg0, arg1, arg2, arg3 });
}
public final PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3, PyObject arg4) {
return invoke(new PyObject[] { arg0, arg1, arg2, arg3, arg4 });
}
public final PyObject invoke(PyObject arg0, PyObject arg1, PyObject arg2, PyObject arg3, PyObject arg4, PyObject arg5) {
return invoke(new PyObject[] { arg0, arg1, arg2, arg3, arg4, arg5 });
}
final void checkArity(PyObject[] args) {
checkArity(args.length);
}
final void checkArity(int got) {
if (got != arity) {
throw Py.TypeError(String.format("expected %d args; got %d", arity, got));
}
}
}
private static final class VoidInvoker extends BaseInvoker {
public VoidInvoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
jffiInvoker.invokeInt(jffiFunction, convertArguments(args));
return Py.None;
}
}
private static final class Signed8Invoker extends BaseInvoker {
public Signed8Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return Util.newSigned8(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Unsigned8Invoker extends BaseInvoker {
public Unsigned8Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return Util.newUnsigned8(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Signed16Invoker extends BaseInvoker {
public Signed16Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newSigned16(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Unsigned16Invoker extends BaseInvoker {
public Unsigned16Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newUnsigned16(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Signed32Invoker extends BaseInvoker {
public Signed32Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newSigned32(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Unsigned32Invoker extends BaseInvoker {
public Unsigned32Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newUnsigned32(jffiInvoker.invokeInt(jffiFunction, convertArguments(args)));
}
}
private static final class Signed64Invoker extends BaseInvoker {
public Signed64Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newSigned64(jffiInvoker.invokeLong(jffiFunction, convertArguments(args)));
}
}
private static final class Unsigned64Invoker extends BaseInvoker {
public Unsigned64Invoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newUnsigned64(jffiInvoker.invokeLong(jffiFunction, convertArguments(args)));
}
}
private static final class FloatInvoker extends BaseInvoker {
public FloatInvoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return Py.newFloat(jffiInvoker.invokeFloat(jffiFunction, convertArguments(args)));
}
}
private static final class DoubleInvoker extends BaseInvoker {
public DoubleInvoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return Py.newFloat(jffiInvoker.invokeDouble(jffiFunction, convertArguments(args)));
}
}
private static final class PointerInvoker extends BaseInvoker {
public PointerInvoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return Py.newLong(jffiInvoker.invokeAddress(jffiFunction, convertArguments(args)));
}
}
private static final class StringInvoker extends BaseInvoker {
private static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance();
public StringInvoker(Function function, ParameterMarshaller[] marshallers) {
super(function, marshallers);
}
public final PyObject invoke(PyObject[] args) {
return JITRuntime.newString(jffiInvoker.invokeAddress(jffiFunction, convertArguments(args)));
}
}
/*------------------------------------------------------------------------*/
static abstract class BaseMarshaller implements ParameterMarshaller {
}
private static class Signed8Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Signed8Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putByte(Util.int8Value(arg));
}
}
private static class Unsigned8Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Unsigned8Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putByte((byte) Util.uint8Value(arg));
}
}
private static class Signed16Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Signed16Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putShort(Util.int16Value(arg));
}
}
private static class Unsigned16Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Unsigned16Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putShort((short) Util.uint16Value(arg));
}
}
private static class Signed32Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Signed32Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putInt(Util.int32Value(arg));
}
}
private static class Unsigned32Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Unsigned32Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putInt((int) Util.uint32Value(arg));
}
}
private static class Signed64Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Signed64Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putLong(Util.int64Value(arg));
}
}
private static class Unsigned64Marshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new Unsigned64Marshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putLong(Util.uint64Value(arg));
}
}
private static class FloatMarshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new FloatMarshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putFloat((float) arg.asDouble());
}
}
private static class DoubleMarshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new DoubleMarshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject arg) {
buffer.putDouble(arg.asDouble());
}
}
private static class StringMarshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new StringMarshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject parameter) {
if (parameter instanceof StringCData) {
buffer.putAddress(((StringCData) parameter).getMemory().getAddress());
} else if (parameter instanceof PyNone) {
buffer.putAddress(0);
} else {
byte[] bytes = parameter.toString().getBytes();
buffer.putArray(bytes, 0, bytes.length,
ArrayFlags.IN | ArrayFlags.NULTERMINATE);
}
}
}
private static class PointerMarshaller extends BaseMarshaller {
public static final ParameterMarshaller INSTANCE = new PointerMarshaller();
public void marshal(HeapInvocationBuffer buffer, PyObject parameter) {
if (parameter instanceof Pointer) {
buffer.putAddress(((Pointer) parameter).getMemory().getAddress());
} else if (parameter == Py.None) {
buffer.putAddress(0);
} else {
throw Py.TypeError("expected pointer argument");
}
}
}
}