DynamicMethod createMethod( RubyModule module, Function function, Type returnType, Type[] parameterTypes) { FastIntMethodFactory factory = this; IntParameterConverter[] parameterConverters = new IntParameterConverter[parameterTypes.length]; IntResultConverter resultConverter = factory.getIntResultConverter(returnType); for (int i = 0; i < parameterConverters.length; ++i) { parameterConverters[i] = factory.getIntParameterConverter(parameterTypes[i]); } switch (parameterTypes.length) { case 0: return new FastIntMethodZeroArg(module, function, resultConverter, parameterConverters); case 1: return new FastIntMethodOneArg(module, function, resultConverter, parameterConverters); case 2: return new FastIntMethodTwoArg(module, function, resultConverter, parameterConverters); case 3: return new FastIntMethodThreeArg(module, function, resultConverter, parameterConverters); default: throw module .getRuntime() .newRuntimeError("Arity " + parameterTypes.length + " not implemented"); } }
DynamicMethod createMethod( RubyModule module, Function function, Type returnType, Type[] parameterTypes, CallingConvention convention, IRubyObject enums) { FunctionInvoker functionInvoker = getFunctionInvoker(returnType); ParameterMarshaller[] marshallers = new ParameterMarshaller[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; ++i) { marshallers[i] = getMarshaller(parameterTypes[i], convention, enums); if (marshallers[i] == null) { throw module .getRuntime() .newTypeError("Could not create marshaller for " + parameterTypes[i]); } } /* * If there is exactly _one_ callback argument to the function, * then a block can be given and automatically subsituted for the callback * parameter. */ if (marshallers.length > 0) { int cbcount = 0, cbindex = -1; for (int i = 0; i < marshallers.length; ++i) { if (marshallers[i] instanceof CallbackMarshaller) { cbcount++; cbindex = i; } } if (cbcount == 1) { return new CallbackMethodWithBlock(module, function, functionInvoker, marshallers, cbindex); } } // // Determine if the parameter might be passed as a 32bit int parameter. // This just applies to buffer/pointer types. // FastIntMethodFactory fastIntFactory = FastIntMethodFactory.getFactory(); boolean canBeFastInt = enums.isNil() && parameterTypes.length <= 3 && fastIntFactory.isFastIntResult(returnType); for (int i = 0; canBeFastInt && i < parameterTypes.length; ++i) { if (!(parameterTypes[i] instanceof Type.Builtin) || marshallers[i].needsInvocationSession()) { canBeFastInt = false; } else { switch (parameterTypes[i].getNativeType()) { case POINTER: case BUFFER_IN: case BUFFER_OUT: case BUFFER_INOUT: canBeFastInt = Platform.getPlatform().addressSize() == 32; break; default: canBeFastInt = fastIntFactory.isFastIntParam(parameterTypes[i]); break; } } } if (!canBeFastInt) switch (parameterTypes.length) { case 0: return new DefaultMethodZeroArg(module, function, functionInvoker); case 1: return new DefaultMethodOneArg(module, function, functionInvoker, marshallers); case 2: return new DefaultMethodTwoArg(module, function, functionInvoker, marshallers); case 3: return new DefaultMethodThreeArg(module, function, functionInvoker, marshallers); default: return new DefaultMethod(module, function, functionInvoker, marshallers); } // // Set up for potentially fast-int operations // IntResultConverter resultConverter = fastIntFactory.getIntResultConverter(returnType); IntParameterConverter[] intParameterConverters = new IntParameterConverter[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; ++i) { intParameterConverters[i] = fastIntFactory.getIntParameterConverter(parameterTypes[i]); } switch (parameterTypes.length) { case 0: return new FastIntMethodZeroArg(module, function, resultConverter, intParameterConverters); case 1: return new FastIntPointerMethodOneArg( module, function, resultConverter, intParameterConverters, marshallers); case 2: return new FastIntPointerMethodTwoArg( module, function, resultConverter, intParameterConverters, marshallers); case 3: return new FastIntPointerMethodThreeArg( module, function, resultConverter, intParameterConverters, marshallers); } throw new IllegalArgumentException("Parameter types not supported"); }