Skip to content

Instantly share code, notes, and snippets.

@headius
Last active September 9, 2021 21:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/73d8717a8fcd3b7b2c00662e7b60b0c5 to your computer and use it in GitHub Desktop.
Save headius/73d8717a8fcd3b7b2c00662e7b60b0c5 to your computer and use it in GitHub Desktop.
diff --git a/core/src/main/java/org/jruby/RubyClass.java b/core/src/main/java/org/jruby/RubyClass.java
index 05a11f97c2..9c3a9793a6 100644
--- a/core/src/main/java/org/jruby/RubyClass.java
+++ b/core/src/main/java/org/jruby/RubyClass.java
@@ -2021,7 +2021,7 @@ public class RubyClass extends RubyModule {
if (supr == null) return;
SkinnyMethodAdapter m = new SkinnyMethodAdapter(cw, ACC_SYNTHETIC | ACC_BRIDGE | ACC_PUBLIC,
- "__super$" + javaMethodName, sig(methodSignature), null, null);
+ "__super$" + JavaNameMangler.mangleMethodName(javaName) + "$" + javaMethodName, sig(methodSignature), null, null);
GeneratorAdapter ga = RealClassGenerator.makeGenerator(m);
ga.loadThis();
ga.loadArgs();
diff --git a/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java b/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
index 03d4f73c49..37aad1d42b 100644
--- a/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
+++ b/core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
@@ -51,6 +51,12 @@ import org.jruby.ir.operands.Splat;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.persistence.IRReader;
import org.jruby.ir.persistence.IRReaderStream;
+import org.jruby.java.invokers.InstanceMethodInvoker;
+import org.jruby.java.invokers.RubyToJavaInvoker;
+import org.jruby.javasupport.JavaMethod;
+import org.jruby.javasupport.proxy.JavaProxyClass;
+import org.jruby.javasupport.proxy.JavaProxyMethod;
+import org.jruby.javasupport.proxy.ReifiedJavaProxy;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Binding;
@@ -1194,6 +1200,24 @@ public class IRRuntimeHelpers {
CacheEntry entry = getSuperMethodEntry(id, definingModule);
DynamicMethod method = entry.method;
+ if (method instanceof InstanceMethodInvoker) {
+ Object javaInvokee = RubyToJavaInvoker.unwrapIfJavaProxy(self);
+
+ if (javaInvokee != self) {
+ JavaMethod javaMethod = (JavaMethod) ((InstanceMethodInvoker) method).findCallable(self, id, args, args.length);
+
+ // self is a Java subclass, need to do a bit more logic to dispatch the right method
+ JavaProxyClass jpc = JavaProxyClass.getProxyClass(context.runtime, (RubyClass) definingModule);
+ JavaProxyMethod jpm;
+ Object[] newArgs = RubyToJavaInvoker.convertArguments(javaMethod, args);
+ if ((jpm = jpc.getMethod(id, javaMethod.getParameterTypes())) != null && jpm.hasSuperImplementation()) {
+ return javaMethod.invokeDirectSuperWithExceptionHandling(context, jpm.getSuperMethod(), javaInvokee, newArgs);
+ } else {
+ return javaMethod.invokeDirectWithExceptionHandling(context, javaMethod.getValue(), javaInvokee, newArgs);
+ }
+ }
+ }
+
if (method.isUndefined()) {
return Helpers.callMethodMissing(context, self, method.getVisibility(), id, CallType.SUPER, args, block);
}
diff --git a/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java b/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java
index 07098ace87..ae1e7f2a72 100644
--- a/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java
+++ b/core/src/main/java/org/jruby/java/invokers/RubyToJavaInvoker.java
@@ -345,7 +345,7 @@ public abstract class RubyToJavaInvoker<T extends JavaCallable> extends JavaMeth
return (JavaProxy) self;
}
- static Object unwrapIfJavaProxy(final IRubyObject object) {
+ public static Object unwrapIfJavaProxy(final IRubyObject object) {
if (object instanceof JavaProxy) {
return ((JavaProxy) object).getObject();
}
@@ -400,7 +400,7 @@ public abstract class RubyToJavaInvoker<T extends JavaCallable> extends JavaMeth
}
}
- protected T findCallable(IRubyObject self, String name, IRubyObject[] args, final int arity) {
+ public T findCallable(IRubyObject self, String name, IRubyObject[] args, final int arity) {
switch (arity) {
case 0:
return findCallableArityZero(self, name);
diff --git a/core/src/main/java/org/jruby/javasupport/JavaCallable.java b/core/src/main/java/org/jruby/javasupport/JavaCallable.java
index d0ec6de4ad..03525a86ba 100644
--- a/core/src/main/java/org/jruby/javasupport/JavaCallable.java
+++ b/core/src/main/java/org/jruby/javasupport/JavaCallable.java
@@ -144,7 +144,7 @@ public abstract class JavaCallable extends JavaAccessibleObject implements Param
return JavaUtil.convertArguments(args, parameterTypes, offset);
}
- protected final IRubyObject handleThrowable(ThreadContext context, final Throwable ex) {
+ protected static IRubyObject handleThrowable(ThreadContext context, final Throwable ex) {
if ( ex instanceof JumpException ) {
// RaiseException (from the Ruby side) is expected to already
// have its stack-trace rewritten - no need to do it again ...
diff --git a/core/src/main/java/org/jruby/javasupport/JavaMethod.java b/core/src/main/java/org/jruby/javasupport/JavaMethod.java
index cdf9a80b00..17b7628669 100644
--- a/core/src/main/java/org/jruby/javasupport/JavaMethod.java
+++ b/core/src/main/java/org/jruby/javasupport/JavaMethod.java
@@ -405,7 +405,7 @@ public class JavaMethod extends JavaCallable {
}
}
- private IRubyObject invokeDirectSuperWithExceptionHandling(ThreadContext context, Method method, Object javaInvokee, Object... arguments) {
+ public IRubyObject invokeDirectSuperWithExceptionHandling(ThreadContext context, Method method, Object javaInvokee, Object... arguments) {
// super calls from proxies must use reflected method
// FIXME: possible to make handles do the superclass call?
try {
@@ -422,7 +422,7 @@ public class JavaMethod extends JavaCallable {
}
}
- private IRubyObject invokeDirectWithExceptionHandling(ThreadContext context, Method method, Object javaInvokee, Object[] arguments) {
+ public IRubyObject invokeDirectWithExceptionHandling(ThreadContext context, Method method, Object javaInvokee, Object[] arguments) {
try {
Object result = method.invoke(javaInvokee, arguments);
return convertReturn(context.runtime, result);
diff --git a/core/src/main/java/org/jruby/javasupport/proxy/JavaProxyClass.java b/core/src/main/java/org/jruby/javasupport/proxy/JavaProxyClass.java
index 06b03c51fa..bfab376611 100644
--- a/core/src/main/java/org/jruby/javasupport/proxy/JavaProxyClass.java
+++ b/core/src/main/java/org/jruby/javasupport/proxy/JavaProxyClass.java
@@ -70,6 +70,7 @@ import org.jruby.javasupport.*;
import org.jruby.runtime.ObjectAllocator;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ClassDefiningClassLoader;
+import org.jruby.util.JavaNameMangler;
import static org.jruby.javasupport.JavaClass.EMPTY_CLASS_ARRAY;
import static org.jruby.javasupport.JavaCallable.inspectParameterTypes;
@@ -393,7 +394,7 @@ public class JavaProxyClass extends JavaProxyReflectionObject {
Method method = proxy.getDeclaredMethod(name, paramTypes);
Method superMethod = null;
if ( hasSuper ) {
- superMethod = proxy.getDeclaredMethod("__super$" + name, paramTypes);
+ superMethod = proxy.getDeclaredMethod("__super$" + JavaNameMangler.mangleMethodName(proxy.getName()) + "$" + name, paramTypes);
}
JavaProxyMethod proxyMethod = new ProxyMethodImpl(getRuntime(), this, method, superMethod);
@@ -407,13 +408,13 @@ public class JavaProxyClass extends JavaProxyReflectionObject {
methodsWithName.add(proxyMethod);
}
catch (ClassNotFoundException e) {
- throw new InternalError(e.getMessage());
+ throw new InternalError(e.getMessage(), e);
}
catch (SecurityException e) {
- throw new InternalError(e.getMessage());
+ throw new InternalError(e.getMessage(), e);
}
catch (NoSuchMethodException e) {
- throw new InternalError(e.getMessage());
+ throw new InternalError(e.getMessage(), e);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment