Skip to content

Commit

Permalink
Showing 5 changed files with 55 additions and 32 deletions.
24 changes: 14 additions & 10 deletions core/src/main/java/org/jruby/RubyModule.java
Original file line number Diff line number Diff line change
@@ -1170,7 +1170,7 @@ public void addMethod(String name, DynamicMethod method) {
addMethodInternal(name, method);
}

public void addMethodInternal(String name, DynamicMethod method) {
public final void addMethodInternal(String name, DynamicMethod method) {
synchronized(methodLocation.getMethodsForWrite()) {
addMethodAtBootTimeOnly(name, method);
invalidateCoreClasses();
@@ -1186,7 +1186,7 @@ public void addMethodInternal(String name, DynamicMethod method) {
* @param name The name to which to bind the method
* @param method The method to bind
*/
public void addMethodAtBootTimeOnly(String name, DynamicMethod method) {
public final void addMethodAtBootTimeOnly(String name, DynamicMethod method) {
if (hasPrepends()) method = new WrapperMethod(methodLocation, method, method.getVisibility());

methodLocation.getMethodsForWrite().put(name, method);
@@ -1195,21 +1195,21 @@ public void addMethodAtBootTimeOnly(String name, DynamicMethod method) {
}

public void removeMethod(ThreadContext context, String name) {
Ruby runtime = context.runtime;

testFrozen("class/module");

if (name.equals("object_id") || name.equals("__send__") || name.equals("initialize")) {
runtime.getWarnings().warn(ID.UNDEFINING_BAD, "removing `" + name + "' may cause serious problems");
switch (name) {
case "object_id" : warnMethodRemoval(context, name); break;
case "__send__" : warnMethodRemoval(context, name); break;
case "initialize" : warnMethodRemoval(context, name); break;
}

// We can safely reference methods here instead of doing getMethods() since if we
// are adding we are not using a IncludedModule.
Map<String, DynamicMethod> methodsForWrite = methodLocation.getMethodsForWrite();
synchronized (methodsForWrite) {
DynamicMethod method = (DynamicMethod) methodsForWrite.remove(name);
DynamicMethod method = methodsForWrite.remove(name);
if (method == null) {
throw runtime.newNameError("method '" + name + "' not defined in " + getName(), name);
throw context.runtime.newNameError("method '" + name + "' not defined in " + getName(), name);
}

invalidateCoreClasses();
@@ -1218,12 +1218,16 @@ public void removeMethod(ThreadContext context, String name) {

if (isSingleton()) {
IRubyObject singleton = ((MetaClass)this).getAttached();
singleton.callMethod(context, "singleton_method_removed", runtime.newSymbol(name));
singleton.callMethod(context, "singleton_method_removed", context.runtime.newSymbol(name));
} else {
callMethod(context, "method_removed", runtime.newSymbol(name));
callMethod(context, "method_removed", context.runtime.newSymbol(name));
}
}

private static void warnMethodRemoval(final ThreadContext context, final String name) {
context.runtime.getWarnings().warn(ID.UNDEFINING_BAD, "removing `" + name + "' may cause serious problems");
}

/**
* Search through this module and supermodules for method definitions. Cache superclass definitions in this class.
*
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -63,7 +64,7 @@
import static org.objectweb.asm.Opcodes.*;

/**
* On fly .class generator (used for Ruby interface impls, sub-classes).
* On fly .class generator (used for Ruby interface impls).
*
* @author headius
*/
@@ -82,6 +83,7 @@ public static Map<String, List<Method>> buildSimpleToAllMap(Class[] interfaces,
superTypeNames[i] = p(interfaces[i]);
for ( Method method : interfaces[i].getMethods() ) {
final String name = method.getName();
if ( Modifier.isStatic(method.getModifiers()) ) continue;
List<Method> methods = simpleToAll.get(name);
if (methods == null) {
simpleToAll.put(name, methods = new ArrayList<Method>(6));
43 changes: 28 additions & 15 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
@@ -194,21 +194,30 @@ public static RubyModule createJavaModule(final Ruby runtime) {
}

public static class OldStyleExtensionInherited {
@Deprecated
public static IRubyObject inherited(IRubyObject self, IRubyObject subclass) {
return inherited(self.getRuntime().getCurrentContext(), self, subclass);
}

@JRubyMethod
public static IRubyObject inherited(IRubyObject self, IRubyObject arg0) {
return Java.concrete_proxy_inherited(self, arg0);
public static IRubyObject inherited(ThreadContext context, IRubyObject self, IRubyObject subclass) {
return invokeProxyClassInherited(context, self, subclass);
}
};

public static class NewStyleExtensionInherited {
@Deprecated
public static IRubyObject inherited(IRubyObject self, IRubyObject subclass) {
return inherited(self.getRuntime().getCurrentContext(), self, subclass);
}

@JRubyMethod
public static IRubyObject inherited(IRubyObject self, IRubyObject arg0) {
final Ruby runtime = self.getRuntime();
if ( ! ( arg0 instanceof RubyClass ) ) {
throw runtime.newTypeError(arg0, runtime.getClassClass());
public static IRubyObject inherited(ThreadContext context, IRubyObject self, IRubyObject subclass) {
if ( ! ( subclass instanceof RubyClass ) ) {
throw context.runtime.newTypeError(subclass, context.runtime.getClassClass());
}
JavaInterfaceTemplate.addRealImplClassNew((RubyClass) arg0);
return runtime.getNil();
JavaInterfaceTemplate.addRealImplClassNew((RubyClass) subclass);
return context.nil;
}
};

@@ -431,7 +440,7 @@ static RubyModule createProxyClassForClass(final Ruby runtime, final Class<?> cl
if (clazz.isInterface()) {
generateInterfaceProxy(runtime, clazz, proxy);
} else {
generateClassProxy(runtime, clazz, (RubyClass)proxy, superClass, javaSupport);
generateClassProxy(runtime, clazz, (RubyClass) proxy, superClass, javaSupport);
}
} finally {
javaSupport.endProxy(clazz);
@@ -536,14 +545,18 @@ public static IRubyObject to_s(ThreadContext context, IRubyObject self) {

}

@Deprecated
public static IRubyObject concrete_proxy_inherited(final IRubyObject clazz, final IRubyObject subclazz) {
final Ruby runtime = clazz.getRuntime();
final ThreadContext context = runtime.getCurrentContext();
JavaSupport javaSupport = runtime.getJavaSupport();
return invokeProxyClassInherited(clazz.getRuntime().getCurrentContext(), clazz, subclazz);
}

private static IRubyObject invokeProxyClassInherited(final ThreadContext context,
final IRubyObject clazz, final IRubyObject subclazz) {
final JavaSupport javaSupport = context.runtime.getJavaSupport();
RubyClass javaProxyClass = javaSupport.getJavaProxyClass().getMetaClass();
Helpers.invokeAs(context, javaProxyClass, clazz, "inherited", subclazz, Block.NULL_BLOCK);
if ( ! ( subclazz instanceof RubyClass ) ) {
throw runtime.newTypeError(subclazz, runtime.getClassClass());
throw context.runtime.newTypeError(subclazz, context.runtime.getClassClass());
}
setupJavaSubclass(context, (RubyClass) subclazz);
return context.nil;
@@ -1328,9 +1341,9 @@ public static Class generateRealClass(final RubyClass clazz) {
String implClassName;
if (clazz.getBaseName() == null) {
// no-name class, generate a bogus name for it
implClassName = "anon_class" + Math.abs(System.identityHashCode(clazz)) + "_" + Math.abs(interfacesHashCode);
implClassName = "anon_class" + Math.abs(System.identityHashCode(clazz)) + '_' + Math.abs(interfacesHashCode);
} else {
implClassName = clazz.getName().replaceAll("::", "\\$\\$") + "_" + Math.abs(interfacesHashCode);
implClassName = clazz.getName().replaceAll("::", "\\$\\$") + '_' + Math.abs(interfacesHashCode);
}
Class<? extends IRubyObject> proxyImplClass;
try {
8 changes: 6 additions & 2 deletions core/src/main/java/org/jruby/javasupport/JavaClass.java
Original file line number Diff line number Diff line change
@@ -73,8 +73,12 @@ public class JavaClass extends JavaObject {

public static final Class[] EMPTY_CLASS_ARRAY = new Class[0];

public JavaClass(final Ruby runtime, final Class<?> javaClass) {
super(runtime, runtime.getJavaSupport().getJavaClassClass(), javaClass);
public JavaClass(final Ruby runtime, final Class<?> klass) {
this(runtime, runtime.getJavaSupport().getJavaClassClass(), klass);
}

JavaClass(final Ruby runtime, final RubyClass javaClassProxy, final Class<?> klass) {
super(runtime, javaClassProxy, klass);
}

@Override
8 changes: 4 additions & 4 deletions core/src/main/java/org/jruby/javasupport/JavaSupportImpl.java
Original file line number Diff line number Diff line change
@@ -108,8 +108,8 @@ public JavaSupportImpl(final Ruby runtime) {

this.javaClassCache = ClassValue.newInstance(new ClassValueCalculator<JavaClass>() {
@Override
public JavaClass computeValue(Class<?> cls) {
return new JavaClass(runtime, cls);
public JavaClass computeValue(Class<?> klass) {
return new JavaClass(runtime, getJavaClassClass(), klass);
}
});

@@ -120,8 +120,8 @@ public JavaClass computeValue(Class<?> cls) {
* allowing us to skip some threading work downstream.
*/
@Override
public synchronized RubyModule computeValue(Class<?> cls) {
return Java.createProxyClassForClass(runtime, cls);
public synchronized RubyModule computeValue(Class<?> klass) {
return Java.createProxyClassForClass(runtime, klass);
}
});

0 comments on commit f7a6bb0

Please sign in to comment.