Example #1
0
 private static IRubyObject callConversionMethod(
     ThreadContext context,
     DynamicMethod method,
     IRubyObject converter,
     String methodName,
     IRubyObject value) {
   if (method.getArity().required() == 2) {
     return method.call(
         context,
         converter,
         converter.getMetaClass(),
         methodName,
         value,
         context.runtime.getNil());
   } else {
     return method.call(context, converter, converter.getMetaClass(), methodName, value);
   }
 }
Example #2
0
    private IRubyObject invokeRuby(
        final DynamicMethod method,
        final JavaProxyMethod proxyMethod,
        final RubyClass metaClass,
        final String name,
        final Object[] nargs) {
      final IRubyObject[] newArgs = new IRubyObject[nargs.length];
      for (int i = nargs.length; --i >= 0; ) {
        newArgs[i] = JavaUtil.convertJavaToUsableRubyObject(runtime, nargs[i]);
      }

      final int arity = method.getArity().getValue();

      if (arity < 0 || arity == newArgs.length) {
        final ThreadContext context = runtime.getCurrentContext();
        return method.call(context, self, metaClass, name, newArgs);
      }
      if (proxyMethod.hasSuperImplementation()) {
        final ThreadContext context = runtime.getCurrentContext();
        final RubyClass superClass = metaClass.getSuperClass();
        return Helpers.invokeAs(context, superClass, self, name, newArgs, Block.NULL_BLOCK);
      }
      throw runtime.newArgumentError(newArgs.length, arity);
    }
Example #3
0
  @JRubyMethod(name = "new", meta = true)
  public static final IRubyObject newMappedType(
      ThreadContext context, IRubyObject klass, IRubyObject converter) {
    if (!converter.respondsTo("native_type")) {
      throw context.runtime.newNoMethodError(
          "converter needs a native_type method", "native_type", converter.getMetaClass());
    }

    DynamicMethod toNativeMethod = converter.getMetaClass().searchMethod("to_native");
    if (toNativeMethod.isUndefined()) {
      throw context.runtime.newNoMethodError(
          "converter needs a to_native method", "to_native", converter.getMetaClass());
    }

    if (toNativeMethod.getArity().required() < 1 || toNativeMethod.getArity().required() > 2) {
      throw context.runtime.newArgumentError("to_native should accept one or two arguments");
    }

    DynamicMethod fromNativeMethod = converter.getMetaClass().searchMethod("from_native");
    if (fromNativeMethod.isUndefined()) {
      throw context.runtime.newNoMethodError(
          "converter needs a from_native method", "from_native", converter.getMetaClass());
    }

    if (fromNativeMethod.getArity().required() < 1 || fromNativeMethod.getArity().required() > 2) {
      throw context.runtime.newArgumentError("from_native should accept one or two arguments");
    }

    Type nativeType;
    try {
      nativeType = (Type) converter.callMethod(context, "native_type");
    } catch (ClassCastException ex) {
      throw context.runtime.newTypeError("native_type did not return instance of FFI::Type");
    }

    boolean isReferenceRequired;
    if (converter.respondsTo("reference_required?")) {
      isReferenceRequired = converter.callMethod(context, "reference_required?").isTrue();

    } else {
      switch (nativeType.nativeType) {
        case BOOL:
        case CHAR:
        case UCHAR:
        case SHORT:
        case USHORT:
        case INT:
        case UINT:
        case LONG:
        case ULONG:
        case LONG_LONG:
        case ULONG_LONG:
        case FLOAT:
        case DOUBLE:
          isReferenceRequired = false;
          break;

        default:
          isReferenceRequired = true;
          break;
      }
    }
    return new MappedType(
        context.runtime,
        (RubyClass) klass,
        nativeType,
        converter,
        toNativeMethod,
        fromNativeMethod,
        isReferenceRequired);
  }