Permalink
Browse files

Use proper original name for frame created via indy logic.

Super still uses frame name to do the lookup of the superclass's
method, so when super is present we have to push a frame with the
name of the currently-executing method. Normally this is the name
at the call site, but when the call is to an aliased method the
original name must be used to invoke the actual method. In the
non-indy logic, this is done by calling through AliasMethod, which
inserts the original name into the call path for use in frames. In
the indy logic, where we unwrap AliasMethod to bind more directly,
we were not carrying along the original name and were always using
the name at the call site. This caused the target method to have
the aliased name in its frame and to attempt to super up that name
instead of the original name.

The fix was to propagate the original name from method unwrapping
through to all places where framing is needed.

In the future, the super name will be statically calculated for
most cases, since it does not change for normal method
definitions.

Fixes #802 and #937.
  • Loading branch information...
1 parent de65320 commit 484b4b44e0218cd186e76778c10478f0cfc0631e @headius headius committed Sep 3, 2013
Showing with 15 additions and 15 deletions.
  1. +15 −15 core/src/main/java/org/jruby/runtime/invokedynamic/InvocationLinker.java
@@ -459,11 +459,10 @@ private static int getNativeArgCount(DynamicMethod method, NativeCall nativeCall
return nativeArgCount;
}
- public static DynamicMethod unwrapMethod(DynamicMethod method) throws IndirectBindingException {
- String name;
+ public static DynamicMethod unwrapMethod(DynamicMethod method, String[] realName) throws IndirectBindingException {
// get the "real" method in a few ways
while (method instanceof AliasMethod) {
- name = ((AliasMethod)method).getOldName(); // need to use original name, not aliased name
+ realName[0] = ((AliasMethod)method).getOldName(); // need to use original name, not aliased name
method = method.getRealMethod();
}
while (method instanceof WrapperMethod) method = method.getRealMethod();
@@ -490,7 +489,7 @@ public IndirectBindingException(String reason) {
public interface HandleGenerator {
public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod method);
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method);
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName);
}
public static class HandleMethodGenerator implements HandleGenerator {
@@ -501,7 +500,7 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
MethodHandle handle = ((HandleMethod)method).getHandle(site.arity());
if (handle == null) {
@@ -541,7 +540,7 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
AttrReaderMethod attrReader = (AttrReaderMethod)method;
String varName = attrReader.getVariableName();
@@ -581,7 +580,7 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
AttrWriterMethod attrReader = (AttrWriterMethod)method;
String varName = attrReader.getVariableName();
@@ -636,7 +635,7 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
// Ruby to FFI
return createFFIHandle(site, method);
}
@@ -676,7 +675,7 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
// Ruby to Java
if (RubyInstanceConfig.LOG_INDY_BINDINGS) LOG.info(site.name() + "\tbound to Java method " + logMethod(method) + ": " + method.getNativeCall());
@@ -708,10 +707,10 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
// Ruby to Ruby
if (RubyInstanceConfig.LOG_INDY_BINDINGS) LOG.info(site.name() + "\tbound to Ruby method " + logMethod(method) + ": " + method.getNativeCall());
- return postProcessNativeHandle(createRubyHandle(site, method, site.name()), site, method, true);
+ return postProcessNativeHandle(createRubyHandle(site, method, realName), site, method, true);
}
}
@@ -737,10 +736,10 @@ public boolean canGenerate(JRubyCallSite site, RubyClass cls, DynamicMethod meth
}
@Override
- public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
+ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod method, String realName) {
// Ruby to Core
if (RubyInstanceConfig.LOG_INDY_BINDINGS) LOG.info(site.name() + "\tbound to native method " + logMethod(method) + ": " + method.getNativeCall());
- return postProcessNativeHandle(createNativeHandle(cls.getClassRuntime(), site, method, site.name()), site, method, true);
+ return postProcessNativeHandle(createNativeHandle(cls.getClassRuntime(), site, method, realName), site, method, true);
}
}
@@ -756,11 +755,12 @@ public MethodHandle generate(JRubyCallSite site, RubyClass cls, DynamicMethod me
);
private static MethodHandle tryDispatchDirect(JRubyCallSite site, RubyClass cls, DynamicMethod method) {
- method = unwrapMethod(method);
+ String[] realName = {site.name()};
+ method = unwrapMethod(method, realName);
for (HandleGenerator generator : HANDLE_GENERATORS) {
if (generator.canGenerate(site, cls, method)) {
- return generator.generate(site, cls, method);
+ return generator.generate(site, cls, method, realName[0]);
}
}

0 comments on commit 484b4b4

Please sign in to comment.