Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  
  package org.jruby.ext.ffi.jffi;
  
 
 
 public final class DefaultMethodFactory extends MethodFactory {
 
     private static final class SingletonHolder {
         private static final DefaultMethodFactory INSTANCE = new DefaultMethodFactory();
     }
     
     public static DefaultMethodFactory getFactory() {
         return .;
     }
 
     private DefaultMethodFactory() {}
 
     
     @Override
     boolean isSupported(Type returnTypeType[] parameterTypesCallingConvention convention) {
         return true;
     }
     
     DynamicMethod createMethod(RubyModule moduleFunction function
             Type returnTypeType[] parameterTypesCallingConvention conventionIRubyObject enumsboolean ignoreError) {
 
         FunctionInvoker functionInvoker = getFunctionInvoker(returnType);
 
         ParameterMarshaller[] marshallers = new ParameterMarshaller[parameterTypes.length];
         for (int i = 0; i < parameterTypes.length; ++i)  {
             marshallers[i] = getMarshaller(parameterTypes[i], conventionenums);
             if (marshallers[i] == null) {
                 throw module.getRuntime().newTypeError("Could not create marshaller for " + parameterTypes[i]);
             }
         }
 
         Signature signature = new Signature(returnTypeparameterTypesconvention
                 ignoreErrorenums instanceof RubyHash ? (RubyHashenums : null);
 
         BufferNativeInvoker fallbackInvoker = new BufferNativeInvoker(modulefunctionsignaturefunctionInvokermarshallers);
         return parameterTypes.length <= 6
             ? new DefaultMethod(modulefunctionsignaturefallbackInvoker)
             : fallbackInvoker;
     }
 
     static FunctionInvoker getFunctionInvoker(Type returnType) {
         if (returnType instanceof Type.Builtin) {
             return getFunctionInvoker(returnType.getNativeType());
 
         } else if (returnType instanceof CallbackInfo) {
             return new ConvertingInvoker(getFunctionInvoker(.), 
                     DataConverters.getResultConverter(returnType));
 
         } else if (returnType instanceof StructByValue) {
             return new StructByValueInvoker((StructByValuereturnType);
         
         } else if (returnType instanceof MappedType) {
             MappedType ctype = (MappedTypereturnType;
             return new ConvertingInvoker(getFunctionInvoker(ctype.getRealType()), 
                     DataConverters.getResultConverter(ctype));
         }
 
         throw returnType.getRuntime().newArgumentError("Cannot get FunctionInvoker for " + returnType);
     }
 
     static FunctionInvoker getFunctionInvoker(NativeType returnType) {
         switch (returnType) {
             case :
                 return .;
             case :
                 return .;
             case :
                return Platform.getPlatform().addressSize() == 32 ? . : .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return Platform.getPlatform().longSize() == 32
                        ? .
                        : .;
            case :
                return Platform.getPlatform().longSize() == 32
                        ? .
                        : .;
            case :
                return .;
            case :
                return .;
            case :
            case :
                return .;
                
            default:
                throw new IllegalArgumentException("Invalid return type: " + returnType);
        }
    }
    
Gets a marshaller to convert from a ruby type to a native type.

Parameters:
type The native type to convert to.
Returns:
A new Marshaller
    static ParameterMarshaller getMarshaller(Type typeCallingConvention conventionIRubyObject enums) {
        if (type instanceof Type.Builtin) {
            return enums != null && !enums.isNil() ? getEnumMarshaller(typeconventionenums) : getMarshaller(type.getNativeType());
        } else if (type instanceof org.jruby.ext.ffi.CallbackInfo) {
            return new ConvertingMarshaller(getMarshaller(type.getNativeType()), 
                    DataConverters.getParameterConverter(typenull));
        } else if (type instanceof org.jruby.ext.ffi.StructByValue) {
            return new StructByValueMarshaller((org.jruby.ext.ffi.StructByValuetype);
        
        } else if (type instanceof org.jruby.ext.ffi.MappedType) {
            MappedType ctype = (MappedTypetype;
            return new ConvertingMarshaller(
                    getMarshaller(ctype.getRealType(), conventionenums), 
                    DataConverters.getParameterConverter(type
                        enums instanceof RubyHash ? (RubyHashenums : null));
        } else {
            return null;
        }
    }

    
Gets a marshaller to convert from a ruby type to a native type.

Parameters:
type The native type to convert to.
enums The enum map
Returns:
A new ParameterMarshaller
    static ParameterMarshaller getEnumMarshaller(Type typeCallingConvention conventionIRubyObject enums) {
        if (!(enums instanceof RubyHash)) {
            throw type.getRuntime().newArgumentError("wrong argument type "
                    + enums.getMetaClass().getName() + " (expected Hash)");
        }
        NativeDataConverter converter = DataConverters.getParameterConverter(type, (RubyHashenums);
        ParameterMarshaller marshaller = getMarshaller(type.getNativeType());
        return converter != null ? new ConvertingMarshaller(marshallerconverter) : marshaller;
    }

    
Gets a marshaller to convert from a ruby type to a native type.

Parameters:
type The native type to convert to.
Returns:
A new ParameterMarshaller
        switch (type) {
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return Platform.getPlatform().longSize() == 32
                        ? .
                        : .;
            case :
                return Platform.getPlatform().longSize() == 32
                        ? .
                        : .;
            case :
                return .;
            case :
                return .;
            case :
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
            case :
                return .;
    
            default:
                throw new IllegalArgumentException("Invalid parameter type: " + type);
        }
    }
    
    private static abstract class BaseInvoker implements FunctionInvoker {
        static final Invoker invoker = Invoker.getInstance();
    }
    
Invokes the native function with no return type, and returns nil to ruby.
    private static final class VoidInvoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new VoidInvoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            .invokeInt(functionargs);
            return context.runtime.getNil();
        }
    }

    
Invokes the native function with a boolean return value. Returns a Boolean to ruby.
    private static final class BooleanInvoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new BooleanInvoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newBoolean(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with n signed 8 bit integer return value. Returns a Fixnum to ruby.
    private static final class Signed8Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Signed8Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newSigned8(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with an unsigned 8 bit integer return value. Returns a Fixnum to ruby.
    private static final class Unsigned8Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Unsigned8Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newUnsigned8(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with n signed 8 bit integer return value. Returns a Fixnum to ruby.
    private static final class Signed16Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Signed16Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newSigned16(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with an unsigned 32 bit integer return value. Returns a Fixnum to ruby.
    private static final class Unsigned16Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Unsigned16Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newUnsigned16(context.invokeInt(functionargs));
        }
    }
    
Invokes the native function with a 32 bit integer return value. Returns a Fixnum to ruby.
    private static final class Signed32Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Signed32Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newSigned32(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with an unsigned 32 bit integer return value. Returns a Fixnum to ruby.
    private static final class Unsigned32Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Unsigned32Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newUnsigned32(context.invokeInt(functionargs));
        }
    }

    
Invokes the native function with a 64 bit integer return value. Returns a Fixnum to ruby.
    private static final class Signed64Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Signed64Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newSigned64(context.invokeLong(functionargs));
        }
    }

    
Invokes the native function with a 64 bit unsigned integer return value. Returns a ruby Fixnum or Bignum.
    private static final class Unsigned64Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Unsigned64Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newUnsigned64(context.invokeLong(functionargs));
        }
    }

    
Invokes the native function with a 32 bit float return value. Returns a Float to ruby.
    private static final class Float32Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Float32Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return context.runtime.newFloat(.invokeFloat(functionargs));
        }
    }

    
Invokes the native function with a 64 bit float return value. Returns a Float to ruby.
    private static final class Float64Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Float64Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return context.runtime.newFloat(.invokeDouble(functionargs));
        }
    }

    
Invokes the native function with a native pointer return value. Returns a org.jruby.ext.ffi.MemoryPointer to ruby.
    private static final class Pointer32Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Pointer32Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newPointer32(context.invokeAddress(functionargs));
        }
    }

    
Invokes the native function with a native pointer return value. Returns a org.jruby.ext.ffi.MemoryPointer to ruby.
    private static final class Pointer64Invoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new Pointer64Invoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newPointer64(context.invokeAddress(functionargs));
        }
    }

    
Invokes the native function with a native string return value. Returns a org.jruby.RubyString to ruby.
    private static final class StringInvoker extends BaseInvoker {
        public static final FunctionInvoker INSTANCE = new StringInvoker();
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return JITRuntime.newString(context.invokeAddress(functionargs));
        }
    }

    
Invokes the native function with a native struct return value. Returns a FFI::Struct instance to ruby.
    private static final class StructByValueInvoker extends BaseInvoker {
        private final StructByValue info;
        public StructByValueInvoker(StructByValue info) {
            this. = info;
        }
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            int size = .getStructLayout().getSize();
            Buffer buf = new Buffer(context.runtimesize);
            MemoryIO mem = buf.getMemoryIO();
            byte[] array;
            int arrayOffset;
            if (mem instanceof ArrayMemoryIO) {
                ArrayMemoryIO arrayMemoryIO = (ArrayMemoryIOmem;
                array = arrayMemoryIO.array();
                arrayOffset = arrayMemoryIO.arrayOffset();
            } else {
                array = new byte[size];
                arrayOffset = 0;
            }
            .invokeStruct(functionargsarrayarrayOffset);
            if (!(mem instanceof ArrayMemoryIO)) {
                mem.put(0, array, 0, array.length);
            }
            return .getStructClass().newInstance(contextbuf.);
        }
    }

    
Invokes the native function, then passes the return value off to a conversion method to massage it to a custom ruby type.
    private static final class ConvertingInvoker extends BaseInvoker {
        private final FunctionInvoker nativeInvoker;
        private final NativeDataConverter converter;
        public ConvertingInvoker(FunctionInvoker nativeInvokerNativeDataConverter converter) {
            this. = nativeInvoker;
            this. = converter;
        }
        public final IRubyObject invoke(ThreadContext contextFunction functionHeapInvocationBuffer args) {
            return .fromNative(context.invoke(contextfunctionargs));
        }
    }
    /*------------------------------------------------------------------------*/
    static abstract class NonSessionMarshaller implements ParameterMarshaller {
        public final boolean requiresPostInvoke() {
            return false;
        }
        public final boolean requiresReference() {
            return false;
        }
        public final void marshal(Invocation invocationInvocationBuffer bufferIRubyObject parameter) {
            marshal(invocation.getThreadContext(), bufferparameter);
        }
    }

    
Converts a ruby Boolean into an 32 bit native integer.
    static final class BooleanMarshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new BooleanMarshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putByte(JITRuntime.boolValue32(parameter));
        }
    }

    
Converts a ruby Fixnum into an 8 bit native integer.
    static final class Signed8Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Signed8Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putByte(JITRuntime.s8Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into an 8 bit native unsigned integer.
    static final class Unsigned8Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Unsigned8Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putByte(JITRuntime.u8Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into a 16 bit native signed integer.
    static final class Signed16Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Signed16Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putShort(JITRuntime.s16Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into a 16 bit native unsigned integer.
    static final class Unsigned16Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Unsigned16Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putShort(JITRuntime.u16Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into a 32 bit native signed integer.
    static final class Signed32Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Signed32Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putInt(JITRuntime.s32Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into a 32 bit native unsigned integer.
    static final class Unsigned32Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Unsigned32Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putInt(JITRuntime.u32Value32(parameter));
        }
    }

    
Converts a ruby Fixnum into a 64 bit native signed integer.
    static final class Signed64Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Signed64Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putLong(JITRuntime.s64Value64(parameter));
        }
    }

    
Converts a ruby Fixnum into a 64 bit native unsigned integer.
    static final class Unsigned64Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Unsigned64Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putLong(JITRuntime.u64Value64(parameter));
        }
    }

    
Converts a ruby Float into a 32 bit native float.
    static final class Float32Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Float32Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putFloat((float) RubyNumeric.num2dbl(parameter));
        }
    }

    
Converts a ruby Float into a 64 bit native float.
    static final class Float64Marshaller extends NonSessionMarshaller {
        public static final ParameterMarshaller INSTANCE = new Float64Marshaller();
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            buffer.putDouble(RubyNumeric.num2dbl(parameter));
        }
    }
    static abstract class PointerParameterMarshaller extends NonSessionMarshaller {
        private final int flags;
        public PointerParameterMarshaller(int flags) {
            this. = flags;
        }
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter,
                                  PointerParameterStrategy strategy) {
            if (strategy.isDirect()) {
                buffer.putAddress(strategy.address(parameter));
            } else {
                buffer.putArray(byte[].class.cast(strategy.object(parameter)), strategy.offset(parameter), strategy.length(parameter),
                        );
            }
        }
    }
    
Converts a ruby Buffer into a native address.
    static final class BufferMarshaller extends PointerParameterMarshaller {
        static final ParameterMarshaller IN = new BufferMarshaller(.);
        static final ParameterMarshaller OUT = new BufferMarshaller(.);
        static final ParameterMarshaller INOUT = new BufferMarshaller(. | .);
        public BufferMarshaller(int flags) {
            super(flags);
        }
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            marshal(contextbufferparameter, JITRuntime.pointerParameterStrategy(parameter));
        }
    }

    
Converts a ruby String into a native pointer.
    static final class StringMarshaller extends PointerParameterMarshaller {
        public static final ParameterMarshaller INSTANCE = new StringMarshaller(. | .);
        StringMarshaller(int flags) {
            super(flags);
        }
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            marshal(contextbufferparameter, JITRuntime.stringParameterStrategy(parameter));
        }
    }

    
Converts a ruby String into a native pointer.
    static final class StructByValueMarshaller extends NonSessionMarshaller {
        private final StructLayout layout;
        public StructByValueMarshaller(org.jruby.ext.ffi.StructByValue sbv) {
             = sbv.getStructLayout();
        }
        public final void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            if (!(parameter instanceof Struct)) {
                throw context.runtime.newTypeError("wrong argument type "
                        + parameter.getMetaClass().getName() + " (expected instance of FFI::Struct)");
            }
            final AbstractMemory memory = ((Structparameter).getMemory();
            if (memory.getSize() < .getSize()) {
                throw context.runtime.newArgumentError("struct memory too small for parameter");
            }
            final MemoryIO io = memory.getMemoryIO();
            if (io.isDirect()) {
                if (io.isNull()) {
                    throw context.runtime.newRuntimeError("Cannot use a NULL pointer as a struct by value argument");
                }
                buffer.putStruct(io.address());
            } else if (io instanceof ArrayMemoryIO) {
                ArrayMemoryIO aio = (ArrayMemoryIOio;
                buffer.putStruct(aio.array(), aio.arrayOffset());
            } else {
                throw context.runtime.newRuntimeError("invalid struct memory");
            }
        }
    }
    
    static final class ConvertingMarshaller implements ParameterMarshaller {
        private final ParameterMarshaller nativeMarshaller;
        private final NativeDataConverter converter;
        public ConvertingMarshaller(ParameterMarshaller nativeMarshallerNativeDataConverter converter) {
            this. = nativeMarshaller;
            this. = converter;
        }
        public void marshal(Invocation invocationInvocationBuffer bufferIRubyObject parameter) {
            ThreadContext context = invocation.getThreadContext();
            final IRubyObject nativeValue = .toNative(contextparameter);
            // keep a hard ref to the converted value if needed
            if (.isReferenceRequired()) {
                invocation.addReference(nativeValue);
            }
            .marshal(contextbuffernativeValue);
        }
        public void marshal(ThreadContext contextInvocationBuffer bufferIRubyObject parameter) {
            .marshal(contextbuffer.toNative(contextparameter));
        }
        public boolean requiresPostInvoke() {
            return .isPostInvokeRequired();
        }
        public boolean requiresReference() {
            return .isReferenceRequired();
        }
    }