下面列出了java.lang.invoke.MethodType#toMethodDescriptorString ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
private Handle generateBootstrapMethod(Handle h) {
String bootstrapName = "bootstrapMethod";
MethodType bootstrapType = MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class);
MethodVisitor bmv = cv.visitMethod(ACC_PUBLIC | ACC_STATIC, bootstrapName, bootstrapType.toMethodDescriptorString(), null, null);
bmv.visitCode();
String constCallSite = "java/lang/invoke/ConstantCallSite";
bmv.visitTypeInsn(NEW, constCallSite);
bmv.visitInsn(DUP);
bmv.visitLdcInsn(h);
bmv.visitMethodInsn(INVOKESPECIAL, constCallSite, "<init>", "(Ljava/lang/invoke/MethodHandle;)V", false);
bmv.visitInsn(ARETURN);
bmv.visitMaxs(0,0);
bmv.visitEnd();
return new Handle(H_INVOKESTATIC, ownerClassName, bootstrapName, bootstrapType.toMethodDescriptorString());
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Test of make method, of class MethodType.
*/
@Test
public void testMake_String_ClassLoader() {
System.out.println("make (from bytecode signature)");
ClassLoader loader = null;
MethodType[] instances = {mt_viS, mt_OO2, mt_vv, mt_Ov, mt_iSI, mt_ISi, mt_ISI, mt_iSi};
String obj = "Ljava/lang/Object;";
assertEquals(obj, concat(Object.class));
String[] expResults = {
"(ILjava/lang/String;)V",
concat("(", obj, 2, ")", Object.class),
"()V", "()"+obj,
concat("(", String.class, Integer.class, ")I"),
concat("(", String.class, "I)", Integer.class),
concat("(", String.class, Integer.class, ")", Integer.class),
concat("(", String.class, "I)I")
};
for (int i = 0; i < instances.length; i++) {
MethodType instance = instances[i];
String result = instance.toMethodDescriptorString();
assertEquals("#"+i, expResults[i], result);
MethodType parsed = MethodType.fromMethodDescriptorString(result, loader);
assertSame("--#"+i, instance, parsed);
}
}
/**
* Converts BoundMethodHandle$Species_L to AbstractInsnNode reference
*
* @param cn
*/
private AbstractInsnNode getOriginalNode(MethodHandle mh, Lookup lookup) throws Exception {
Field original = mh.getClass().getDeclaredField("argL0");
original.setAccessible(true);
MethodHandle originalHandle = (MethodHandle) original.get(mh);
MethodHandleInfo direct = lookup.revealDirect(originalHandle);
int refKind = direct.getReferenceKind();
Class<?> declaringClass = direct.getDeclaringClass();
String name = direct.getName();
MethodType methodType = direct.getMethodType();
int op = -1;
if (refKind <= 4) {
switch (refKind) {
case 1:
op = GETFIELD;
break;
case 2:
op = GETSTATIC;
break;
case 3:
op = PUTFIELD;
break;
case 4:
op = PUTSTATIC;
break;
}
String desc;
if (refKind <= 2) {
desc = methodType.toMethodDescriptorString().substring(2);
} else {
// method handle treats field setting as a method (returning void)
String mds = methodType.toMethodDescriptorString();
desc = mds.substring(1, mds.lastIndexOf(')'));
}
return new FieldInsnNode(op, declaringClass.getName().replace('.', '/'), name, desc);
}
switch (refKind) {
case 5:
op = INVOKEVIRTUAL;
break;
case 6:
op = INVOKESTATIC;
break;
case 7:
case 8:
op = INVOKESPECIAL;
break;
case 9:
op = INVOKEINTERFACE;
break;
}
return new MethodInsnNode(op, declaringClass.getName().replace('.', '/'), name,
methodType.toMethodDescriptorString());
}
/**
* Generate this method, including the code and exception table entry.
*/
private void generateMethod(ClassWriter cw, String className) {
MethodType mt = MethodType.methodType(returnType, parameterTypes);
String desc = mt.toMethodDescriptorString();
MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_FINAL,
method.getName(), desc, null,
typeNames(Arrays.asList(exceptionTypes)));
int[] parameterSlot = new int[parameterTypes.length];
int nextSlot = 1;
for (int i = 0; i < parameterSlot.length; i++) {
parameterSlot[i] = nextSlot;
nextSlot += getWordsPerType(parameterTypes[i]);
}
mv.visitCode();
Label L_startBlock = new Label();
Label L_endBlock = new Label();
Label L_RuntimeHandler = new Label();
Label L_ThrowableHandler = new Label();
List<Class<?>> catchList = computeUniqueCatchList(exceptionTypes);
if (catchList.size() > 0) {
for (Class<?> ex : catchList) {
mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_RuntimeHandler,
dotToSlash(ex.getName()));
}
mv.visitTryCatchBlock(L_startBlock, L_endBlock, L_ThrowableHandler,
JL_THROWABLE);
}
mv.visitLabel(L_startBlock);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, JLR_PROXY, handlerFieldName,
LJLR_INVOCATION_HANDLER);
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETSTATIC, dotToSlash(className), methodFieldName,
LJLR_METHOD);
if (parameterTypes.length > 0) {
// Create an array and fill with the parameters converting primitives to wrappers
emitIconstInsn(mv, parameterTypes.length);
mv.visitTypeInsn(Opcodes.ANEWARRAY, JL_OBJECT);
for (int i = 0; i < parameterTypes.length; i++) {
mv.visitInsn(DUP);
emitIconstInsn(mv, i);
codeWrapArgument(mv, parameterTypes[i], parameterSlot[i]);
mv.visitInsn(Opcodes.AASTORE);
}
} else {
mv.visitInsn(Opcodes.ACONST_NULL);
}
mv.visitMethodInsn(INVOKEINTERFACE, JLR_INVOCATION_HANDLER,
"invoke",
"(Ljava/lang/Object;Ljava/lang/reflect/Method;" +
"[Ljava/lang/Object;)Ljava/lang/Object;", true);
if (returnType == void.class) {
mv.visitInsn(POP);
mv.visitInsn(RETURN);
} else {
codeUnwrapReturnValue(mv, returnType);
}
mv.visitLabel(L_endBlock);
// Generate exception handler
mv.visitLabel(L_RuntimeHandler);
mv.visitInsn(ATHROW); // just rethrow the exception
mv.visitLabel(L_ThrowableHandler);
mv.visitVarInsn(ASTORE, 1);
mv.visitTypeInsn(Opcodes.NEW, JLR_UNDECLARED_THROWABLE_EX);
mv.visitInsn(DUP);
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKESPECIAL, JLR_UNDECLARED_THROWABLE_EX,
"<init>", "(Ljava/lang/Throwable;)V", false);
mv.visitInsn(ATHROW);
// Maxs computed by ClassWriter.COMPUTE_FRAMES, these arguments ignored
mv.visitMaxs(-1, -1);
mv.visitEnd();
}
@Override
public MethodVisitor visitMethod(final int access, final String name,
final String desc, final String signature,
final String[] exceptions) {
/* a code generate looks like
* 0: aload_0
* 1: ldc #125 // int 1
* 3: ldc2_w #126 // long 2l
* 6: ldc #128 // float 3.0f
* 8: ldc2_w #129 // double 4.0d
* 11: ldc #132 // String 5
* 13: aload_0
* 14: getfield #135 // Field nativeCallee:Z
* 17: ifeq 28
* 20: invokedynamic #181, 0 // InvokeDynamic #1:calleeNative:(Lcompiler/calls/common/InvokeDynamic;IJFDLjava/lang/String;)Z
* 25: goto 33
* 28: invokedynamic #183, 0 // InvokeDynamic #1:callee:(Lcompiler/calls/common/InvokeDynamic;IJFDLjava/lang/String;)Z
* 33: ldc #185 // String Call insuccessfull
* 35: invokestatic #191 // Method jdk/test/lib/Asserts.assertTrue:(ZLjava/lang/String;)V
* 38: return
*
* or, using java-like pseudo-code
* if (this.nativeCallee == false) {
* invokedynamic-call-return-value = invokedynamic-of-callee
* } else {
* invokedynamic-call-return-value = invokedynamic-of-nativeCallee
* }
* Asserts.assertTrue(invokedynamic-call-return-value, error-message);
* return;
*/
if (name.equals(CALLER_METHOD_NAME)) {
MethodVisitor mv = cv.visitMethod(access, name, desc,
signature, exceptions);
Label nonNativeLabel = new Label();
Label checkLabel = new Label();
MethodType mtype = MethodType.methodType(CallSite.class,
MethodHandles.Lookup.class, String.class, MethodType.class);
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, CLASS,
BOOTSTRAP_METHOD_NAME, mtype.toMethodDescriptorString());
mv.visitCode();
// push callee parameters onto stack
mv.visitVarInsn(Opcodes.ALOAD, 0);//push "this"
mv.visitLdcInsn(1);
mv.visitLdcInsn(2L);
mv.visitLdcInsn(3.0f);
mv.visitLdcInsn(4.0d);
mv.visitLdcInsn("5");
// params loaded. let's decide what method to call
mv.visitVarInsn(Opcodes.ALOAD, 0); // push "this"
// get nativeCallee field
mv.visitFieldInsn(Opcodes.GETFIELD, CLASS, CALL_NATIVE_FIELD,
CALL_NATIVE_FIELD_DESC);
// if nativeCallee == false goto nonNativeLabel
mv.visitJumpInsn(Opcodes.IFEQ, nonNativeLabel);
// invokedynamic nativeCalleeMethod using bootstrap method
mv.visitInvokeDynamicInsn(NATIVE_CALLEE_METHOD_NAME,
CALLEE_METHOD_DESC, bootstrap);
// goto checkLabel
mv.visitJumpInsn(Opcodes.GOTO, checkLabel);
// label: nonNativeLabel
mv.visitLabel(nonNativeLabel);
// invokedynamic calleeMethod using bootstrap method
mv.visitInvokeDynamicInsn(CALLEE_METHOD_NAME, CALLEE_METHOD_DESC,
bootstrap);
mv.visitLabel(checkLabel);
mv.visitLdcInsn(CallsBase.CALL_ERR_MSG);
mv.visitMethodInsn(Opcodes.INVOKESTATIC, ASSERTS_CLASS,
ASSERTTRUE_METHOD_NAME, ASSERTTRUE_METHOD_DESC, false);
// label: return
mv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
return null;
}
return super.visitMethod(access, name, desc, signature, exceptions);
}