use of org.objectweb.asm.Handle in project es6draft by anba.
the class SimpleTypeTextifier method visitInvokeDynamicInsn.
@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
buf.setLength(0);
buf.append(tab2).append("INVOKEDYNAMIC").append(' ').append(name);
appendDescriptor(METHOD_DESCRIPTOR, desc);
if (bsmArgs.length != 0) {
buf.append(" [");
for (int i = 0; i < bsmArgs.length; ++i) {
Object arg = bsmArgs[i];
if (arg instanceof String) {
appendString(buf, (String) arg);
} else if (arg instanceof Type) {
Type type = (Type) arg;
if (type.getSort() == Type.METHOD) {
appendDescriptor(METHOD_DESCRIPTOR, type.getDescriptor());
} else {
appendDescriptor(INTERNAL_NAME, type.getDescriptor());
}
} else if (arg instanceof Handle) {
Handle handle = (Handle) arg;
appendDescriptor(HANDLE_DESCRIPTOR, getMethodDescriptor(handle.getDesc()));
} else {
buf.append(arg);
}
if (i + 1 < bsmArgs.length) {
buf.append(", ");
}
}
buf.append("]");
}
buf.append("\n");
text.add(buf.toString());
}
use of org.objectweb.asm.Handle in project bazel by bazelbuild.
the class LambdaDesugaring method queueUpBridgeMethodIfNeeded.
/**
* Makes {@link #visitEnd} generate a bridge method for the given method handle if the
* referenced method will be invisible to the generated lambda class.
*
* @return struct containing either {@code invokedMethod} or {@code invokedMethod} and a handle
* representing the bridge method that will be generated for {@code invokedMethod}.
*/
private MethodReferenceBridgeInfo queueUpBridgeMethodIfNeeded(Handle invokedMethod) throws ClassNotFoundException {
if (invokedMethod.getName().startsWith("lambda$")) {
// We adjust lambda bodies to be visible
return MethodReferenceBridgeInfo.noBridge(invokedMethod);
}
// invokedMethod is a method reference if we get here
Executable invoked = findTargetMethod(invokedMethod);
if (isVisibleToLambdaClass(invoked, invokedMethod.getOwner())) {
// Referenced method is visible to the generated class, so nothing to do
return MethodReferenceBridgeInfo.noBridge(invokedMethod);
}
// We need a bridge method if we get here
checkState(!isInterface, "%s is an interface and shouldn't need bridge to %s", internalName, invokedMethod);
checkState(!invokedMethod.isInterface(), "%s's lambda classes can't see interface method: %s", internalName, invokedMethod);
MethodReferenceBridgeInfo result = bridgeMethods.get(invokedMethod);
if (result != null) {
// we're already queued up a bridge method for this method reference
return result;
}
String name = uniqueInPackage(internalName, "bridge$lambda$" + bridgeMethods.size());
Handle bridgeMethod;
switch(invokedMethod.getTag()) {
case Opcodes.H_INVOKESTATIC:
bridgeMethod = new Handle(invokedMethod.getTag(), internalName, name, invokedMethod.getDesc(), /*itf*/
false);
break;
case Opcodes.H_INVOKEVIRTUAL:
case // we end up calling these using invokevirtual
Opcodes.H_INVOKESPECIAL:
bridgeMethod = new Handle(Opcodes.H_INVOKEVIRTUAL, internalName, name, invokedMethod.getDesc(), /*itf*/
false);
break;
case Opcodes.H_NEWINVOKESPECIAL:
{
// Call invisible constructor through generated bridge "factory" method, so we need to
// compute the descriptor for the bridge method from the constructor's descriptor
String desc = Type.getMethodDescriptor(Type.getObjectType(invokedMethod.getOwner()), Type.getArgumentTypes(invokedMethod.getDesc()));
bridgeMethod = new Handle(Opcodes.H_INVOKESTATIC, internalName, name, desc, /*itf*/
false);
break;
}
case Opcodes.H_INVOKEINTERFACE:
// Shouldn't get here
default:
throw new UnsupportedOperationException("Cannot bridge " + invokedMethod);
}
result = MethodReferenceBridgeInfo.bridge(invokedMethod, invoked, bridgeMethod);
MethodReferenceBridgeInfo old = bridgeMethods.put(invokedMethod, result);
checkState(old == null, "Already had bridge %s so we don't also want %s", old, result);
return result;
}
use of org.objectweb.asm.Handle in project bazel by bazelbuild.
the class LambdaDesugaring method visitEnd.
@Override
public void visitEnd() {
for (Map.Entry<Handle, MethodReferenceBridgeInfo> bridge : bridgeMethods.entrySet()) {
Handle original = bridge.getKey();
Handle neededMethod = bridge.getValue().bridgeMethod();
checkState(neededMethod.getTag() == Opcodes.H_INVOKESTATIC || neededMethod.getTag() == Opcodes.H_INVOKEVIRTUAL, "Cannot generate bridge method %s to reach %s", neededMethod, original);
checkState(bridge.getValue().referenced() != null, "Need referenced method %s to generate bridge %s", original, neededMethod);
int access = Opcodes.ACC_BRIDGE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_FINAL;
if (neededMethod.getTag() == Opcodes.H_INVOKESTATIC) {
access |= Opcodes.ACC_STATIC;
}
MethodVisitor bridgeMethod = super.visitMethod(access, neededMethod.getName(), neededMethod.getDesc(), (String) null, toInternalNames(bridge.getValue().referenced().getExceptionTypes()));
// Bridge is a factory method calling a constructor
if (original.getTag() == Opcodes.H_NEWINVOKESPECIAL) {
bridgeMethod.visitTypeInsn(Opcodes.NEW, original.getOwner());
bridgeMethod.visitInsn(Opcodes.DUP);
}
int slot = 0;
if (neededMethod.getTag() != Opcodes.H_INVOKESTATIC) {
bridgeMethod.visitVarInsn(Opcodes.ALOAD, slot++);
}
Type neededType = Type.getMethodType(neededMethod.getDesc());
for (Type arg : neededType.getArgumentTypes()) {
bridgeMethod.visitVarInsn(arg.getOpcode(Opcodes.ILOAD), slot);
slot += arg.getSize();
}
bridgeMethod.visitMethodInsn(invokeOpcode(original), original.getOwner(), original.getName(), original.getDesc(), original.isInterface());
bridgeMethod.visitInsn(neededType.getReturnType().getOpcode(Opcodes.IRETURN));
// rely on class writer to compute these
bridgeMethod.visitMaxs(0, 0);
bridgeMethod.visitEnd();
}
super.visitEnd();
}
use of org.objectweb.asm.Handle in project elasticsearch by elastic.
the class SFunction method initializeConstant.
private void initializeConstant(MethodWriter writer) {
final Handle handle = new Handle(Opcodes.H_INVOKESTATIC, CLASS_TYPE.getInternalName(), name, method.method.getDescriptor(), false);
writer.push(handle);
}
use of org.objectweb.asm.Handle in project lombok by rzwitserloot.
the class SneakyThrowsRemover method applyTransformations.
@Override
public byte[] applyTransformations(byte[] original, String fileName, final DiagnosticsReceiver diagnostics) {
if (!new ClassFileMetaData(original).usesMethod("lombok/Lombok", "sneakyThrow"))
return null;
byte[] fixedByteCode = fixJSRInlining(original);
ClassReader reader = new ClassReader(fixedByteCode);
ClassWriter writer = new ClassWriter(reader, 0);
final AtomicBoolean changesMade = new AtomicBoolean();
class SneakyThrowsRemoverVisitor extends MethodVisitor {
SneakyThrowsRemoverVisitor(MethodVisitor mv) {
super(Opcodes.ASM5, mv);
}
private boolean methodInsnQueued = false;
@Override
public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
if (opcode == Opcodes.INVOKESTATIC && "sneakyThrow".equals(name) && "lombok/Lombok".equals(owner) && "(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;".equals(desc)) {
if (System.getProperty("lombok.debugAsmOnly", null) != null) {
// DEBUG for issue 470!
super.visitMethodInsn(opcode, owner, name, desc, itf);
} else {
methodInsnQueued = true;
}
} else {
super.visitMethodInsn(opcode, owner, name, desc, itf);
}
}
private void handleQueue() {
if (!methodInsnQueued)
return;
super.visitMethodInsn(Opcodes.INVOKESTATIC, "lombok/Lombok", "sneakyThrow", "(Ljava/lang/Throwable;)Ljava/lang/RuntimeException;", false);
methodInsnQueued = false;
diagnostics.addWarning("Proper usage is: throw lombok.Lombok.sneakyThrow(someException);. You did not 'throw' it. Because of this, the call to sneakyThrow " + "remains in your classfile and you will need lombok.jar on the classpath at runtime.");
}
@Override
public void visitInsn(int arg0) {
if (methodInsnQueued && arg0 == Opcodes.ATHROW) {
changesMade.set(true);
// As expected, the required ATHROW. We can now safely 'eat' the previous call.
methodInsnQueued = false;
}
handleQueue();
super.visitInsn(arg0);
}
@Override
public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3, Object[] arg4) {
handleQueue();
super.visitFrame(arg0, arg1, arg2, arg3, arg4);
}
@Override
public void visitIincInsn(int arg0, int arg1) {
handleQueue();
super.visitIincInsn(arg0, arg1);
}
@Override
public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {
handleQueue();
super.visitFieldInsn(arg0, arg1, arg2, arg3);
}
@Override
public void visitIntInsn(int arg0, int arg1) {
handleQueue();
super.visitIntInsn(arg0, arg1);
}
@Override
public void visitEnd() {
handleQueue();
super.visitEnd();
}
@Override
public void visitInvokeDynamicInsn(String arg0, String arg1, Handle arg2, Object... arg3) {
handleQueue();
super.visitInvokeDynamicInsn(arg0, arg1, arg2, arg3);
}
@Override
public void visitLabel(Label arg0) {
handleQueue();
super.visitLabel(arg0);
}
@Override
public void visitJumpInsn(int arg0, Label arg1) {
handleQueue();
super.visitJumpInsn(arg0, arg1);
}
@Override
public void visitLdcInsn(Object arg0) {
handleQueue();
super.visitLdcInsn(arg0);
}
@Override
public void visitLocalVariable(String arg0, String arg1, String arg2, Label arg3, Label arg4, int arg5) {
handleQueue();
super.visitLocalVariable(arg0, arg1, arg2, arg3, arg4, arg5);
}
@Override
public void visitMaxs(int arg0, int arg1) {
handleQueue();
super.visitMaxs(arg0, arg1);
}
@Override
public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {
handleQueue();
super.visitLookupSwitchInsn(arg0, arg1, arg2);
}
@Override
public void visitMultiANewArrayInsn(String arg0, int arg1) {
handleQueue();
super.visitMultiANewArrayInsn(arg0, arg1);
}
@Override
public void visitVarInsn(int arg0, int arg1) {
handleQueue();
super.visitVarInsn(arg0, arg1);
}
@Override
public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2, String arg3) {
handleQueue();
super.visitTryCatchBlock(arg0, arg1, arg2, arg3);
}
@Override
public void visitTableSwitchInsn(int arg0, int arg1, Label arg2, Label... arg3) {
handleQueue();
super.visitTableSwitchInsn(arg0, arg1, arg2, arg3);
}
@Override
public void visitTypeInsn(int arg0, String arg1) {
handleQueue();
super.visitTypeInsn(arg0, arg1);
}
}
reader.accept(new ClassVisitor(Opcodes.ASM5, writer) {
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
return new SneakyThrowsRemoverVisitor(super.visitMethod(access, name, desc, signature, exceptions));
}
}, 0);
return changesMade.get() ? writer.toByteArray() : null;
}
Aggregations