Allow changing of lambda SAM types (alter method descriptor)
This is currently the 'slow' implementation and actually slows down invokeinterface too - need to get the fast version done...
This commit is contained in:
@@ -362,4 +362,16 @@ public class GlobalConfiguration {
|
||||
}
|
||||
debugplugins = debugPlugins;
|
||||
}
|
||||
|
||||
public final static boolean isJava18orHigher;
|
||||
|
||||
static {
|
||||
String version = System.getProperty("java.version");
|
||||
if (version.startsWith("1.8")) {
|
||||
isJava18orHigher = true;
|
||||
}
|
||||
else {
|
||||
isJava18orHigher = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1236,8 +1236,15 @@ public class MethodInvokerRewriter {
|
||||
|
||||
mv.visitLdcInsn(name + desc); // [targetInstance paramArray targetInstance nameAndDescriptor]
|
||||
|
||||
// calling __execute(params array, this, name+desc)
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, owner, mDynamicDispatchName, mDynamicDispatchDescriptor);
|
||||
if (GlobalConfiguration.isJava18orHigher) {
|
||||
// if the target is a generated lambda callsite object then calling __execute isn't going to work as those
|
||||
// types don't have the method in them!
|
||||
mv.visitMethodInsn(INVOKESTATIC, tRegistryType, "iiIntercept", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;");
|
||||
}
|
||||
else {
|
||||
// calling __execute(params array, this, name+desc)
|
||||
mv.visitMethodInsn(INVOKEINTERFACE, owner, mDynamicDispatchName, mDynamicDispatchDescriptor);
|
||||
}
|
||||
|
||||
insertAppropriateReturn(returnType);
|
||||
Label gotolabel = new Label();
|
||||
|
||||
@@ -1259,6 +1259,33 @@ public class TypeRegistry {
|
||||
return null; // let it fail anyway
|
||||
}
|
||||
|
||||
/**
|
||||
* See notes.md#001
|
||||
*
|
||||
*/
|
||||
public static Object iiIntercept(Object instance, Object[] params, Object instance2, String nameAndDescriptor) {
|
||||
Class<?> clazz= instance.getClass();
|
||||
try {
|
||||
if (clazz.getName().contains("$$Lambda")) {
|
||||
// There will only be one method, the SAM method
|
||||
Method[] ms = instance.getClass().getDeclaredMethods();
|
||||
Method m = ms[0];
|
||||
m.setAccessible(true);
|
||||
Object o = m.invoke(instance, params);
|
||||
return o;
|
||||
}
|
||||
else {
|
||||
// Do what you were going to do...
|
||||
Method m = instance.getClass().getDeclaredMethod("__execute",Object[].class,Object.class,String.class);
|
||||
m.setAccessible(true);
|
||||
return m.invoke(instance, params, instance, nameAndDescriptor);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@UsedByGeneratedCode
|
||||
public static __DynamicallyDispatchable ispcheck(int ids, String nameAndDescriptor) {
|
||||
if (GlobalConfiguration.isRuntimeLogging && log.isLoggable(Level.FINER)) {
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.springsource.loaded.TypeRegistry;
|
||||
import org.springsource.loaded.Utils;
|
||||
import org.springsource.loaded.SystemClassReflectionRewriter.RewriteResult;
|
||||
import org.springsource.loaded.ri.ReflectiveInterceptor;
|
||||
import org.springsource.loaded.support.Java8;
|
||||
|
||||
/**
|
||||
* The entry point for the agent - all classes that can be modified will be passed into preProcess(). They have to be dealt with in
|
||||
@@ -148,6 +149,10 @@ public class SpringLoadedPreProcessor implements Constants {
|
||||
// return rr.bytes;
|
||||
// }
|
||||
}
|
||||
else if (slashedClassName.equals("java/lang/invoke/InnerClassLambdaMetafactory")) {
|
||||
bytes = Java8.enhanceInnerClassLambdaMetaFactory(bytes);
|
||||
return bytes;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@@ -140,4 +140,15 @@ public class Java8 {
|
||||
|
||||
return LambdaMetafactory.metafactory(caller, invokedName, invokedType, samMethodType, implMethod, instantiatedMethodType);
|
||||
}
|
||||
|
||||
/**
|
||||
* The metafactory we are enhancing is responsible for generating the anonymous classes that will call the lambda methods in our type
|
||||
*
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
public static byte[] enhanceInnerClassLambdaMetaFactory(byte[] bytes) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user