下面列出了org.objectweb.asm.Handle#getOwner ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private void invokeDynamicOnLambda(MethodVisitor mv, AbstractInsnNode ain) {
InvokeDynamicInsnNode indy = (InvokeDynamicInsnNode)ain;
Object[]bsmArgs = indy.bsmArgs;
// Is it a lambda conversion
if (indy.bsm.getOwner().equals("java/lang/invoke/LambdaMetafactory")) {
Handle lambdaBody = (Handle)bsmArgs[1];
Detector detector = this.methodFlow.detector();
String desc = lambdaBody.getDesc();
//if (detector.isPausable(lambdaBody.getOwner(), lambdaBody.getName(), desc)) {
//if(!lambdaBody.getName().equals("<init>")) {
bsmArgs[0] = addFiberType((org.objectweb.asm.Type)bsmArgs[0]);
bsmArgs[1] = new Handle(lambdaBody.getTag(),
lambdaBody.getOwner(),
lambdaBody.getName(),
desc.replace(")", D_FIBER + ")"));
bsmArgs[2] = addFiberType((org.objectweb.asm.Type)bsmArgs[2]);
//}
//}
}
ain.accept(mv);
}
protected void _dynamic_call(Handle bsm, Object[] bsmArgs, String bootstrapDesc, String boundName) {
save_stack(false);
// these are the additional bound variables passed into the boostrap method (typically metafactory)
Expr[] boundArgs = new Expr[Type.getArgumentTypes(bootstrapDesc).length];
for(int i = boundArgs.length - 1; i >= 0; i--) {
boundArgs[i] = pop();
}
// copy the bsm and bsm args
Handle bsmCopy = new Handle(bsm.getTag(), bsm.getOwner(), bsm.getName(), bsm.getDesc());
Handle provider = new Handle(bsm.getTag(), bsm.getOwner(), bsm.getName(), bsm.getDesc());
Object[] bsmArgsCopy = new Object[bsmArgs.length];
System.arraycopy(bsmArgs, 0, bsmArgsCopy, 0, bsmArgsCopy.length);
DynamicInvocationExpr expr = new DynamicInvocationExpr(bsmCopy, bsmArgsCopy, bootstrapDesc, boundArgs, boundName);
if(expr.getType() == Type.VOID_TYPE) {
addStmt(new PopStmt(expr));
} else {
int index = currentStack.height();
Type type = assign_stack(index, expr);
push(load_stack(index, type));
}
// TODO: redo vm lambdas as static resolution calls/concrete calls.
}
@Override
public void visitInvokeDynamicInsn(String origMethodName, String methodDescriptor, Handle bootstrapMethodHandle, Object... bootstrapMethodArguments) {
String methodOwner = bootstrapMethodHandle.getOwner();
if (isStringConcatIndy(methodOwner, origMethodName)) {
handleStringConcatIndy(origMethodName, methodDescriptor, bootstrapMethodHandle, bootstrapMethodArguments);
} else if (isLambdaIndy(methodOwner)) {
// AKI-130: The bootstrap methodDescriptor to this metafactory must NOT require additional arguments (since that would require dynamic class generation for each callsite - potential attack vector).
if (!methodDescriptor.startsWith("()")) {
throw RejectedClassException.invokeDynamicBootstrapMethodArguments(methodDescriptor);
}
// This is really just a specialization of the above call to check the return type (this would need to be changed if we accepted arguments).
if (!RUNNABLE_DESCRIPTOR.equals(methodDescriptor) && !FUNCTION_DESCRIPTOR.equals(methodDescriptor)) {
throw RejectedClassException.invokeDynamicLambdaType(methodDescriptor);
}
if (bootstrapMethodHandle.getTag() != Opcodes.H_INVOKEVIRTUAL && bootstrapMethodHandle.getTag() != Opcodes.H_INVOKESTATIC
&& bootstrapMethodHandle.getTag() != Opcodes.H_NEWINVOKESPECIAL && bootstrapMethodHandle.getTag() != Opcodes.H_INVOKEINTERFACE) {
throw RejectedClassException.invokeDynamicHandleType(bootstrapMethodHandle.getTag(), methodDescriptor);
}
handleLambdaIndy(origMethodName, methodDescriptor, bootstrapMethodHandle, bootstrapMethodArguments);
} else {
throw RejectedClassException.invokeDynamicUnsupportedMethodOwner(origMethodName, methodOwner);
}
}
/**
* Mutates a handle within an invoke virtual.
*/
private Handle mutateHandle(Handle handle) {
int opcode = handle.getTag();
String owner = handle.getOwner();
String name = handle.getName();
String descriptor = handle.getDesc();
if (owner.equals(expectedOwner) && opcode == Opcodes.H_INVOKEVIRTUAL) {
if (REPLACEMENTS.containsKey(name)) {
Replacement replacement = REPLACEMENTS.get(name);
if (replacement.descriptor.equals(descriptor)) {
MutationIdentifier id = context.registerMutation(factory, replacement.toString());
if (context.shouldMutate(id)) {
return new Handle(
opcode,
owner,
replacement.destinationName,
descriptor,
handle.isInterface());
}
}
}
}
return handle;
}
public DynamicInvocationExpr(Handle bootstrapMethod, Object[] bootstrapArgs, String bootstrapDesc, Expr[] args, String boundName) {
super(CallType.DYNAMIC, args, bootstrapMethod.getOwner(), bootstrapMethod.getName(), bootstrapDesc);
this.bootstrapMethod = bootstrapMethod;
this.bootstrapArgs = bootstrapArgs;
this.boundName = boundName;
assert(Type.getArgumentTypes(bootstrapDesc).length == args.length); // I hope this tells me when this fucks up, because this is not a matter of if, but when.
for(int i = 0; i < args.length; i++) {
writeAt(args[i], i);
}
}
/**
* @param methodHandle The pre-transform method handle.
* @param mapMethodDescriptor True if the underlying descriptor should be mapped or false to leave it unchanged.
* @return The post-transform method handle.
*/
public Handle mapHandle(Handle methodHandle, boolean mapMethodDescriptor, boolean preserveDebuggability) {
String methodOwner = methodHandle.getOwner();
String methodName = methodHandle.getName();
String methodDescriptor = methodHandle.getDesc();
String newMethodOwner = mapType(methodOwner, preserveDebuggability);
String newMethodName = mapMethodName(methodName);
String newMethodDescriptor = mapMethodDescriptor ? mapDescriptor(methodDescriptor, preserveDebuggability) : methodDescriptor;
return new Handle(methodHandle.getTag(), newMethodOwner, newMethodName, newMethodDescriptor, methodHandle.isInterface());
}
private Handle newLambdaHandleFrom(Handle origHandle, boolean shadowMethodDescriptor) {
final String owner = origHandle.getOwner();
final String newOwner = owner;
final String newMethodName = origHandle.getName();
final String newMethodDescriptor = shadowMethodDescriptor ? replacer.replaceMethodDescriptor(origHandle.getDesc()) : origHandle.getDesc();
return new Handle(origHandle.getTag(), newOwner, newMethodName, newMethodDescriptor, origHandle.isInterface());
}