예제 #1
0
  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");
    }
  }
예제 #2
0
  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");
  }