コード例 #1
0
ファイル: SuperInstr.java プロジェクト: ryfow/jruby
  protected Object interpretSuper(
      ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) {
    // SSS FIXME: We should check in the current module (for instance methods) or the current
    // module's meta class (for class methods)
    //
    // RubyModule currM = context.getCurrentScope().getStaticScope().getModule();
    // RubyModule klazz = (isInstanceMethodSuper) ? currM : currM.getMetaClass();
    //
    // The question is how do we know what this 'super' ought to do?
    // For 'super' that occurs in a method scope, this is easy to figure out.
    // But, what about 'super' that occurs in block scope?  How do we figure that out?
    RubyModule klazz = context.getFrameKlazz();

    // SSS FIXME: Even though we may know the method name in some instances,
    // we are not making use of it here.
    String methodName = context.getCurrentFrame().getName(); // methAddr.getName();

    checkSuperDisabledOrOutOfMethod(context, klazz, methodName);
    RubyClass superClass =
        RuntimeHelpers.findImplementerIfNecessary(self.getMetaClass(), klazz).getSuperClass();
    DynamicMethod method =
        superClass != null ? superClass.searchMethod(methodName) : UndefinedMethod.INSTANCE;

    Object rVal =
        method.isUndefined()
            ? RuntimeHelpers.callMethodMissing(
                context, self, method.getVisibility(), methodName, CallType.SUPER, args, block)
            : method.call(context, self, superClass, methodName, args, block);

    return hasUnusedResult() ? null : rVal;
  }
コード例 #2
0
ファイル: SuperInstr.java プロジェクト: yokolet/jruby
  @Override
  public Object interpret(
      ThreadContext context,
      DynamicScope currDynScope,
      IRubyObject self,
      Object[] temp,
      Block aBlock) {
    // FIXME: Receiver is not being used...should we be retrieving it?
    IRubyObject receiver = (IRubyObject) getReceiver().retrieve(context, self, currDynScope, temp);
    IRubyObject[] args = prepareArguments(context, self, getCallArgs(), currDynScope, temp);
    Block block = prepareBlock(context, self, currDynScope, temp);
    RubyModule klazz = context.getFrameKlazz();
    // SSS FIXME: Even though we may know the method name in some instances,
    // we are not making use of it here.  It is cleaner in the sense of not
    // relying on implicit information whose data flow doesn't show up in the IR.
    String methodName = context.getCurrentFrame().getName(); // methAddr.getName();

    checkSuperDisabledOrOutOfMethod(context, klazz, methodName);
    RubyClass superClass =
        RuntimeHelpers.findImplementerIfNecessary(self.getMetaClass(), klazz).getSuperClass();
    DynamicMethod method =
        superClass != null ? superClass.searchMethod(methodName) : UndefinedMethod.INSTANCE;

    Object rVal =
        method.isUndefined()
            ? RuntimeHelpers.callMethodMissing(
                context, self, method.getVisibility(), methodName, CallType.SUPER, args, block)
            : method.call(context, self, superClass, methodName, args, block);

    return hasUnusedResult() ? null : rVal;
  }
コード例 #3
0
 protected static boolean methodMissing(
     CacheEntry entry, CallType callType, String name, IRubyObject caller) {
   DynamicMethod method = entry.method;
   return method.isUndefined()
       || (callType == CallType.NORMAL
           && !name.equals("method_missing")
           && !method.isCallableFrom(caller, callType));
 }
コード例 #4
0
ファイル: RuntimeCache.java プロジェクト: ribrdb/jruby
 private DynamicMethod cacheAndGet(
     ThreadContext context, RubyClass selfType, int index, String methodName) {
   CacheEntry entry = selfType.searchWithCache(methodName);
   DynamicMethod method = entry.method;
   if (method.isUndefined()) {
     return RuntimeHelpers.selectMethodMissing(
         context, selfType, method.getVisibility(), methodName, CallType.FUNCTIONAL);
   }
   methodCache[index] = entry;
   return method;
 }
コード例 #5
0
ファイル: SelfInvokeSite.java プロジェクト: cthulhua/jruby
  @Override
  public boolean methodMissing(CacheEntry entry, IRubyObject caller) {
    DynamicMethod method = entry.method;

    return method.isUndefined();
  }
コード例 #6
0
ファイル: MappedType.java プロジェクト: nahi/jruby
  @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);
  }