Skip to content

Commit

Permalink
move (and name for easier debug) proc-to-iface method_missing method …
Browse files Browse the repository at this point in the history
…from JavaUtil
  • Loading branch information
kares committed Mar 25, 2015
1 parent 7bf94dd commit 58487dd
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 29 deletions.
30 changes: 30 additions & 0 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
import org.jruby.RubyMethod;
import org.jruby.RubyModule;
import org.jruby.RubyObject;
import org.jruby.RubyProc;
import org.jruby.RubyString;
import org.jruby.RubyUnboundMethod;
import org.jruby.javasupport.binding.Initializer;
Expand All @@ -78,6 +79,7 @@
import org.jruby.anno.JRubyMethod;
import org.jruby.anno.JRubyModule;
import org.jruby.exceptions.RaiseException;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodN;
import org.jruby.internal.runtime.methods.JavaMethod.JavaMethodZero;
import org.jruby.java.addons.ArrayJavaAddons;
Expand Down Expand Up @@ -1104,6 +1106,34 @@ public Arity getArity() {

}

final static class ProcToInterface extends org.jruby.internal.runtime.methods.DynamicMethod {

ProcToInterface(final RubyClass singletonClass) {
super(singletonClass, PUBLIC, org.jruby.internal.runtime.methods.CallConfiguration.FrameNoneScopeNone);
}

@Override // method_missing impl :
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
if ( ! ( self instanceof RubyProc ) ) {
throw context.runtime.newTypeError("interface impl method_missing for block used with non-Proc object");
}
final RubyProc proc = (RubyProc) self;
final IRubyObject[] newArgs;
if ( args.length == 1 ) newArgs = IRubyObject.NULL_ARRAY;
else {
newArgs = new IRubyObject[ args.length - 1 ];
System.arraycopy(args, 1, newArgs, 0, newArgs.length);
}
return proc.call(context, newArgs);
}

@Override
public DynamicMethod dup() {
return this;
}

}

@JRubyMethod(meta = true)
public static IRubyObject const_missing(final ThreadContext context,
final IRubyObject self, final IRubyObject name) {
Expand Down
32 changes: 3 additions & 29 deletions core/src/main/java/org/jruby/javasupport/JavaUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,6 @@
import org.jruby.RubyProc;
import org.jruby.RubyString;
import org.jruby.RubyTime;
import org.jruby.internal.runtime.methods.CallConfiguration;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.java.proxies.ArrayJavaProxy;
import org.jruby.java.proxies.JavaProxy;
import org.jruby.java.proxies.RubyObjectHolderProxy;
Expand All @@ -84,7 +82,6 @@
import org.jruby.runtime.Block;
import org.jruby.runtime.ClassIndex;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;

import org.jruby.util.ByteList;
Expand Down Expand Up @@ -233,7 +230,7 @@ public static boolean isDuckTypeConvertable(Class providedArgumentType, Class pa
}

public static Object convertProcToInterface(ThreadContext context, RubyObject rubyObject, Class target) {
return convertProcToInterface(context, (RubyBasicObject)rubyObject, target);
return convertProcToInterface(context, (RubyBasicObject) rubyObject, target);
}

public static Object convertProcToInterface(ThreadContext context, RubyBasicObject rubyObject, Class target) {
Expand All @@ -248,31 +245,8 @@ public static Object convertProcToInterface(ThreadContext context, RubyBasicObje
if ( rubyObject instanceof RubyProc ) {
// Proc implementing an interface, pull in the catch-all code that lets the proc get invoked
// no matter what method is called on the interface
RubyClass singletonClass = rubyObject.getSingletonClass();

singletonClass.addMethod("method_missing", new DynamicMethod(singletonClass, Visibility.PUBLIC, CallConfiguration.FrameNoneScopeNone) {

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
if (!(self instanceof RubyProc)) {
throw context.runtime.newTypeError("interface impl method_missing for block used with non-Proc object");
}
RubyProc proc = (RubyProc)self;
IRubyObject[] newArgs;
if (args.length == 1) {
newArgs = IRubyObject.NULL_ARRAY;
} else {
newArgs = new IRubyObject[args.length - 1];
System.arraycopy(args, 1, newArgs, 0, args.length - 1);
}
return proc.call(context, newArgs);
}

@Override
public DynamicMethod dup() {
return this;
}
});
final RubyClass singletonClass = rubyObject.getSingletonClass();
singletonClass.addMethod("method_missing", new Java.ProcToInterface(singletonClass));
}
JavaObject javaObject = (JavaObject) Helpers.invoke(context, rubyObject, "__jcreate_meta!");
return javaObject.getValue();
Expand Down

0 comments on commit 58487dd

Please sign in to comment.