Skip to content

Commit

Permalink
Continue propagating name through JavaMethod subtypes.
Browse files Browse the repository at this point in the history
headius committed Jan 31, 2018
1 parent 577d13a commit 74d4306
Showing 13 changed files with 334 additions and 143 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -1338,7 +1338,7 @@ private void initRoot() {

// In 1.9 and later, Kernel.gsub is defined only when '-p' or '-n' is given on the command line
if (config.getKernelGsubDefined()) {
kernel.addMethod("gsub", new JavaMethod(kernel, Visibility.PRIVATE) {
kernel.addMethod("gsub", new JavaMethod(kernel, Visibility.PRIVATE, "gsub") {

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyKernel.java
Original file line number Diff line number Diff line change
@@ -106,7 +106,7 @@ public static class MethodMissingMethod extends JavaMethodNBlock {
private final CallType callType;

public MethodMissingMethod(RubyModule implementationClass, Visibility visibility, CallType callType) {
super(implementationClass, Visibility.PRIVATE);
super(implementationClass, Visibility.PRIVATE, "method_missing");

this.callType = callType;
this.visibility = visibility;
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -1871,7 +1871,7 @@ public IRubyObject newMethod(IRubyObject receiver, final String methodName, bool
public static class RespondToMissingMethod extends JavaMethod.JavaMethodNBlock {
final CallSite site;
public RespondToMissingMethod(RubyModule implClass, Visibility vis, String methodName) {
super(implClass, vis);
super(implClass, vis, methodName);

setParameterList(REST);
site = new FunctionalCachingCallSite(methodName);
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/anno/AnnotationBinder.java
Original file line number Diff line number Diff line change
@@ -318,7 +318,7 @@ public void processMethodDeclaration(ExecutableElement method) {
anno.frame());
String implClass = anno.meta() ? "singletonClass" : "cls";

out.println(" javaMethod = new " + annotatedBindingName + "(" + implClass + ", Visibility." + anno.visibility() + ");");
out.println(" javaMethod = new " + annotatedBindingName + "(" + implClass + ", Visibility." + anno.visibility() + ", \"" + method.getSimpleName() + "\");");
out.println(" populateMethod(javaMethod, " +
+AnnotationHelper.getArityValue(anno, actualRequired) + ", \""
+ method.getSimpleName() + "\", "
@@ -364,7 +364,7 @@ public void processMethodDeclarationMulti(ExecutableElement method) {
anno.frame());
String implClass = anno.meta() ? "singletonClass" : "cls";

out.println(" javaMethod = new " + annotatedBindingName + "(" + implClass + ", Visibility." + anno.visibility() + ");");
out.println(" javaMethod = new " + annotatedBindingName + "(" + implClass + ", Visibility." + anno.visibility() + ", \"" + method.getSimpleName() + "\");");
out.println(" populateMethod(javaMethod, " +
"-1, \"" +
method.getSimpleName() + "\", " +
10 changes: 9 additions & 1 deletion core/src/main/java/org/jruby/anno/IndyBinder.java
Original file line number Diff line number Diff line change
@@ -403,6 +403,7 @@ public void processMethodDeclarationMulti(List<ExecutableElement> methods) {

mv.aload(implClass);
mv.getstatic(p(Visibility.class), anno.visibility().name(), ci(Visibility.class));
mv.ldc(getBaseNameFor(anno.name(), methods.get(0)));
mv.ldc(encodeSignature(0, 0, 0, 0, 0, true, false));
mv.ldc(true);
mv.ldc(anno.notImplemented());
@@ -424,7 +425,7 @@ public void processMethodDeclarationMulti(List<ExecutableElement> methods) {
}
}

Method handleInit = Method.getMethod("void foo(org.jruby.RubyModule, org.jruby.runtime.Visibility, long, boolean, boolean, java.lang.String, int, int, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable)");
Method handleInit = Method.getMethod("void foo(org.jruby.RubyModule, org.jruby.runtime.Visibility, java.lang.String, long, boolean, boolean, java.lang.String, int, int, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable, java.util.concurrent.Callable)");
mv.invokespecial("org/jruby/internal/runtime/methods/HandleMethod", "<init>", handleInit.getDescriptor());

mv.astore(BASEMETHOD);
@@ -604,4 +605,11 @@ private void defineMethodOnClass(int methodVar, int classVar, final String[] nam
}
}
}

protected String getBaseNameFor(String[] names, ExecutableElement md) {
if (names.length == 0) {
return md.getSimpleName().toString();
}
return names[0];
}
}
32 changes: 22 additions & 10 deletions core/src/main/java/org/jruby/ext/pathname/RubyPathname.java
Original file line number Diff line number Diff line change
@@ -136,16 +136,7 @@ public IRubyObject[] addArg(IRubyObject[] args, RubyString path) {
private static void defineDelegateMethodsGeneric(RubyClass cPathname, final RubyModule klass,
final ReturnValueMapper mapper, final AddArg addArg, String... methods) {
for (String method : methods) {
cPathname.addMethod(method, new JavaMethod.JavaMethodNBlock(cPathname,
Visibility.PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject _self, RubyModule clazz,
String name, IRubyObject[] args, Block block) {
RubyPathname self = (RubyPathname) _self;
args = addArg.addArg(args, self.getPath());
return mapper.map(context, (RubyClass) clazz, klass.callMethod(context, name, args, block));
}
});
cPathname.addMethod(method, new PathnameDelegateMethod(cPathname, method, addArg, mapper, klass));
}
}

@@ -436,4 +427,25 @@ private static RubyArray mapToPathnames(ThreadContext context, RubyClass clazz,
}
return paths;
}

private static class PathnameDelegateMethod extends JavaMethod.JavaMethodNBlock {
private final AddArg addArg;
private final ReturnValueMapper mapper;
private final RubyModule klass;

public PathnameDelegateMethod(RubyClass cPathname, String method, AddArg addArg, ReturnValueMapper mapper, RubyModule klass) {
super(cPathname, Visibility.PUBLIC, method);
this.addArg = addArg;
this.mapper = mapper;
this.klass = klass;
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject _self, RubyModule clazz,
String name, IRubyObject[] args, Block block) {
RubyPathname self = (RubyPathname) _self;
args = addArg.addArg(args, self.getPath());
return mapper.map(context, (RubyClass) clazz, klass.callMethod(context, name, args, block));
}
}
}
Original file line number Diff line number Diff line change
@@ -122,7 +122,7 @@ public class InvocationMethodFactory extends MethodFactory implements Opcodes {
params(ThreadContext.class, IRubyObject.class, RubyModule.class, String.class, IRubyObject.class, IRubyObject.class, IRubyObject.class));

/** The super constructor signature for Java-based method handles. */
private final static String JAVA_SUPER_SIG = sig(Void.TYPE, params(RubyModule.class, Visibility.class));
private final static String JAVA_SUPER_SIG = sig(Void.TYPE, params(RubyModule.class, Visibility.class, String.class));

/** The lvar index of "this" */
public static final int THIS_INDEX = 0;
@@ -187,7 +187,7 @@ public InvocationMethodFactory(ClassLoader classLoader) {
// return signature.isFixed() && signature.required() <= 3;
//}

private static final Class[] RubyModule_and_Visibility = new Class[]{ RubyModule.class, Visibility.class };
private static final Class[] RubyModule_and_Visibility_and_Name = new Class[]{ RubyModule.class, Visibility.class, String.class };

/**
* Use code generation to provide a method handle based on an annotated Java
@@ -208,7 +208,7 @@ public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, List<Jav
DescriptorInfo info = new DescriptorInfo(descs);
if (DEBUG) LOG.debug(" min: " + info.getMin() + ", max: " + info.getMax());

JavaMethod ic = (JavaMethod) c.getConstructor(RubyModule_and_Visibility).newInstance(implementationClass, anno.visibility());
JavaMethod ic = (JavaMethod) c.getConstructor(RubyModule_and_Visibility_and_Name).newInstance(implementationClass, anno.visibility(), desc1.name);

TypePopulator.populateMethod(
ic,
@@ -324,7 +324,7 @@ public DynamicMethod getAnnotatedMethod(RubyModule implementationClass, JavaMeth
try {
Class c = getAnnotatedMethodClass(Collections.singletonList(desc));

JavaMethod ic = (JavaMethod) c.getConstructor(RubyModule_and_Visibility).newInstance(implementationClass, desc.anno.visibility());
JavaMethod ic = (JavaMethod) c.getConstructor(RubyModule_and_Visibility_and_Name).newInstance(implementationClass, desc.anno.visibility(), desc.name);

TypePopulator.populateMethod(
ic,
@@ -419,7 +419,7 @@ private static ClassWriter createJavaMethodCtor(String namePath, String sup, Str
cw.visitSource(sourceFile, null);
SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cw, ACC_PUBLIC, "<init>", JAVA_SUPER_SIG, null, null);
mv.start();
mv.aloadMany(0, 1, 2);
mv.aloadMany(0, 1, 2, 3);
mv.invokespecial(sup, "<init>", JAVA_SUPER_SIG);
mv.aload(0);
mv.ldc(parameterDesc);
387 changes: 279 additions & 108 deletions core/src/main/java/org/jruby/internal/runtime/methods/JavaMethod.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -72,7 +72,7 @@ public abstract class RubyToJavaInvoker<T extends JavaCallable> extends JavaMeth

@SuppressWarnings("unchecked") // NULL_CACHE
RubyToJavaInvoker(RubyModule host, Member member) {
super(host, Visibility.PUBLIC);
super(host, Visibility.PUBLIC, member.getName());
this.runtime = host.getRuntime();

final T callable;
@@ -98,7 +98,7 @@ public abstract class RubyToJavaInvoker<T extends JavaCallable> extends JavaMeth

@SuppressWarnings("unchecked") // NULL_CACHE
RubyToJavaInvoker(RubyModule host, Member[] members) {
super(host, Visibility.PUBLIC);
super(host, Visibility.PUBLIC, members[0].getName());
this.runtime = host.getRuntime();

// initialize all the callables for this method
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ private static final class InitializeMethod extends org.jruby.internal.runtime.m

private final CallSite jcreateSite = MethodIndex.getFunctionalCallSite("__jcreate!");

InitializeMethod(final RubyClass clazz) { super(clazz, Visibility.PRIVATE); }
InitializeMethod(final RubyClass clazz, final String name) { super(clazz, Visibility.PRIVATE, name); }

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
@@ -177,7 +177,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
}

protected static void initialize(final RubyClass ConcreteJavaProxy) {
ConcreteJavaProxy.addMethod("initialize", new InitializeMethod(ConcreteJavaProxy));
ConcreteJavaProxy.addMethod("initialize", new InitializeMethod(ConcreteJavaProxy, "initialize"));
// We define a custom "new" method to ensure that __jcreate! is getting called,
// so that if the user doesn't call super in their subclasses, the object will
// still get set up properly. See JRUBY-4704.
Original file line number Diff line number Diff line change
@@ -78,7 +78,7 @@ public static IRubyObject implement(ThreadContext context, IRubyObject self, IRu
private static class DummyMethodImpl extends org.jruby.internal.runtime.methods.JavaMethod {

DummyMethodImpl(RubyModule targetModule) {
super(targetModule, Visibility.PUBLIC);
super(targetModule, Visibility.PUBLIC, "dummy");
}

@Override
@@ -414,7 +414,7 @@ private static final class BlockInterfaceImpl extends JavaMethod {
private final Block implBlock;

BlockInterfaceImpl(final RubyClass implClass, final Block implBlock, final IRubyObject[] methodNames) {
super(implClass, Visibility.PUBLIC);
super(implClass, Visibility.PUBLIC, "block_interface_impl");
this.implBlock = implBlock; this.methodNames = methodNames;
}

@@ -460,11 +460,11 @@ public final IRubyObject call(ThreadContext context, IRubyObject self, RubyModul

public DynamicMethod dup() { return this; }

final ConcreteMethod getConcreteMethod() { return new ConcreteMethod(); }
final ConcreteMethod getConcreteMethod() { return new ConcreteMethod(name); }

private final class ConcreteMethod extends JavaMethod {

ConcreteMethod() {
ConcreteMethod(String name) {
super(BlockInterfaceImpl.this.implementationClass, Visibility.PUBLIC);
}

10 changes: 5 additions & 5 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
@@ -498,7 +498,7 @@ else if ( clazz == Object.class ) {
// solved here by adding an exception-throwing "inherited"
if ( Modifier.isFinal(clazz.getModifiers()) ) {
final String clazzName = clazz.getCanonicalName();
proxy.getMetaClass().addMethod("inherited", new org.jruby.internal.runtime.methods.JavaMethod(proxy, PUBLIC) {
proxy.getMetaClass().addMethod("inherited", new org.jruby.internal.runtime.methods.JavaMethod(proxy, PUBLIC, "inherited") {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
throw context.runtime.newTypeError("can not extend final Java class: " + clazzName);
@@ -1052,7 +1052,7 @@ private static boolean bindJavaPackageOrClassMethod(final RubyModule parentPacka
}

final RubyClass singleton = parentPackage.getSingletonClass();
singleton.addMethod(name.intern(), new JavaAccessor(singleton, packageOrClass, parentPackage));
singleton.addMethod(name, new JavaAccessor(singleton, packageOrClass, parentPackage, name));
return true;
}

@@ -1061,8 +1061,8 @@ private static class JavaAccessor extends org.jruby.internal.runtime.methods.Jav
private final RubyModule packageOrClass;
private final RubyModule parentPackage;

JavaAccessor(final RubyClass singleton, final RubyModule packageOrClass, final RubyModule parentPackage) {
super(singleton, PUBLIC);
JavaAccessor(final RubyClass singleton, final RubyModule packageOrClass, final RubyModule parentPackage, final String name) {
super(singleton, PUBLIC, name);
this.parentPackage = parentPackage; this.packageOrClass = packageOrClass;
}

@@ -1125,7 +1125,7 @@ public DynamicMethod dup() {
final class ConcreteMethod extends org.jruby.internal.runtime.methods.JavaMethod {

ConcreteMethod() {
super(ProcToInterface.this.implementationClass, Visibility.PUBLIC);
super(ProcToInterface.this.implementationClass, Visibility.PUBLIC, "proc_to_interface");
}

@Override
Original file line number Diff line number Diff line change
@@ -39,7 +39,7 @@ void addConstructor(final Constructor ctor, final Class<?> clazz) {
proxy.addMethod(name, new ConstructorInvoker(proxy, constructors));
}
else { // if there's no constructor, we must prevent construction
proxy.addMethod(name, new org.jruby.internal.runtime.methods.JavaMethod(proxy, PUBLIC) {
proxy.addMethod(name, new org.jruby.internal.runtime.methods.JavaMethod(proxy, PUBLIC, name) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
throw context.runtime.newTypeError("no public constructors for " + clazz);

0 comments on commit 74d4306

Please sign in to comment.