List of usage examples for org.objectweb.asm Opcodes ACC_PUBLIC
int ACC_PUBLIC
To view the source code for org.objectweb.asm Opcodes ACC_PUBLIC.
Click Source Link
From source file:de.zib.sfs.instrument.RandomAccessFileAdapter.java
License:BSD License
@Override protected void appendWrappedMethods(ClassVisitor visitor) { ResultPasser resultDiscarder = new DiscardResultPasser(); wrapMethod(Opcodes.ACC_PRIVATE, "open", Type.VOID_TYPE, new Type[] { Type.getType(String.class), Type.INT_TYPE }, null, new String[] { Type.getInternalName(FileNotFoundException.class) }, "openCallback", Type.getType(String.class), new ParameterResultPasser(1)); // for all read methods pass the read result to the callback ReturnResultPasser resultPasser = new ReturnResultPasser(); // invokes .length on an array ResultPasser arrayLengthPasser = new ParameterResultPasser(1) { @Override//from www .j a va2s. c om public void passResult(MethodVisitor mv) { mv.visitInsn(Opcodes.ARRAYLENGTH); } }; // invokes .length(); on the current local variable ResultPasser stringLengthPasser = new ReturnResultPasser() { @Override public void passResult(MethodVisitor mv) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(String.class), "length", Type.getMethodDescriptor(Type.INT_TYPE), false); } }; if (!skipReads()) { wrapMethod(Opcodes.ACC_PUBLIC, "read", Type.INT_TYPE, null, null, new String[] { Type.getInternalName(IOException.class) }, "readCallback", Type.INT_TYPE, resultPasser); wrapMethod(Opcodes.ACC_PUBLIC, "read", Type.INT_TYPE, new Type[] { Type.getType(byte[].class) }, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, resultPasser); wrapMethod(Opcodes.ACC_PUBLIC, "read", Type.INT_TYPE, new Type[] { Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE }, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, resultPasser); wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "readFully", Type.VOID_TYPE, new Type[] { Type.getType(byte[].class) }, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, arrayLengthPasser); wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "readFully", Type.VOID_TYPE, new Type[] { Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE }, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, new ParameterResultPasser(3)); // record length of read string wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "readLine", Type.getType(String.class), null, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, stringLengthPasser); wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "readUTF", Type.getType(String.class), null, null, new String[] { Type.getInternalName(IOException.class) }, "readBytesCallback", Type.INT_TYPE, stringLengthPasser); } // take length of parameter string instead of return value stringLengthPasser = new ParameterResultPasser(1) { @Override public void passResult(MethodVisitor mv) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(String.class), "length", Type.getMethodDescriptor(Type.INT_TYPE), false); } }; if (!skipWrites()) { // 1 byte write, no result needed wrapMethod(Opcodes.ACC_PUBLIC, "write", Type.VOID_TYPE, new Type[] { Type.INT_TYPE }, null, new String[] { Type.getInternalName(IOException.class) }, "writeCallback", null, resultDiscarder); // have the byte array put on top of the stack, then pass its length // to // the callback wrapMethod(Opcodes.ACC_PUBLIC, "write", Type.VOID_TYPE, new Type[] { Type.getType(byte[].class) }, null, new String[] { Type.getInternalName(IOException.class) }, "writeBytesCallback", Type.INT_TYPE, arrayLengthPasser); // have the len parameter put on top of the stack wrapMethod(Opcodes.ACC_PUBLIC, "write", Type.VOID_TYPE, new Type[] { Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE }, null, new String[] { Type.getInternalName(IOException.class) }, "writeBytesCallback", Type.INT_TYPE, new ParameterResultPasser(3)); wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "writeBytes", Type.VOID_TYPE, new Type[] { Type.getType(String.class) }, null, new String[] { Type.getInternalName(IOException.class) }, "writeBytesCallback", Type.INT_TYPE, stringLengthPasser); // twice the data if written as characters wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "writeChars", Type.VOID_TYPE, new Type[] { Type.getType(String.class) }, null, new String[] { Type.getInternalName(IOException.class) }, "writeBytesCallback", Type.INT_TYPE, new ParameterResultPasser(1) { @Override public void passResult(MethodVisitor mv) { mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(String.class), "length", Type.getMethodDescriptor(Type.INT_TYPE), false); mv.visitInsn(Opcodes.ICONST_2); mv.visitInsn(Opcodes.IMUL); } }); wrapMethod(Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL, "writeUTF", Type.VOID_TYPE, new Type[] { Type.getType(String.class) }, null, new String[] { Type.getInternalName(IOException.class) }, "writeBytesCallback", Type.INT_TYPE, stringLengthPasser); } }
From source file:de.zib.sfs.instrument.RandomAccessFileAdapter.java
License:BSD License
private boolean isReadFullyMethod(int access, String name, String desc, String signature, String[] exceptions) { return access == (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL) && "readFully".equals(name) && (Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(byte[].class)).equals(desc) || Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(byte[].class), Type.INT_TYPE, Type.INT_TYPE).equals(desc)) && null == signature && exceptions != null && exceptions.length == 1 && Type.getInternalName(IOException.class).equals(exceptions[0]) && !skipReads(); }
From source file:de.zib.sfs.instrument.RandomAccessFileAdapter.java
License:BSD License
private boolean isReadStringMethod(int access, String name, String desc, String signature, String[] exceptions) {//from ww w . j a va 2s . c o m return access == (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL) && ("readLine".equals(name) || "readUTF".equals(name)) && Type.getMethodDescriptor(Type.getType(String.class)).equals(desc) && null == signature && exceptions != null && exceptions.length == 1 && Type.getInternalName(IOException.class).equals(exceptions[0]) && !skipReads(); }
From source file:de.zib.sfs.instrument.RandomAccessFileAdapter.java
License:BSD License
private boolean isWriteStringMethod(int access, String name, String desc, String signature, String[] exceptions) {//from w w w.j ava 2s . com return access == (Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL) && ("writeBytes".equals(name) || "writeChars".equals(name) || "writeUTF".equals(name)) && Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class)).equals(desc) && null == signature && exceptions != null && exceptions.length == 1 && Type.getInternalName(IOException.class).equals(exceptions[0]) && !skipWrites(); }
From source file:de.zib.sfs.instrument.ZipFileAdapter.java
License:BSD License
@Override public void visitEnd() { if (!this.skip.contains(OperationCategory.ZIP)) { // public void close() { MethodVisitor closeMethodMV = this.cv.visitMethod(Opcodes.ACC_PUBLIC, "close", Type.getMethodDescriptor(Type.VOID_TYPE), null, new String[] { Type.getInternalName(IOException.class) }); closeMethodMV.visitCode();//w ww. j av a 2 s .co m // ZipFileCallback.closeCallback(jzfile); closeMethodMV.visitVarInsn(Opcodes.ALOAD, 0); closeMethodMV.visitFieldInsn(Opcodes.GETFIELD, Type.getInternalName(ZipFile.class), "jzfile", Type.getDescriptor(Long.TYPE)); closeMethodMV.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(ZipFileCallback.class), "closeCallback", Type.getMethodDescriptor(Type.VOID_TYPE, Type.LONG_TYPE), false); // methodPrefixclose(); closeMethodMV.visitVarInsn(Opcodes.ALOAD, 0); closeMethodMV.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(ZipFile.class), this.methodPrefix + "close", Type.getMethodDescriptor(Type.VOID_TYPE), false); // } closeMethodMV.visitInsn(Opcodes.RETURN); closeMethodMV.visitMaxs(0, 0); closeMethodMV.visitEnd(); } this.cv.visitEnd(); }
From source file:de.zib.sfs.instrument.ZipFileAdapter.java
License:BSD License
private boolean isConstructor(int access, String name, String desc, String signature, String[] exceptions) { return Opcodes.ACC_PUBLIC == access && "<init>".equals(name) && desc.equals(this.constructorDescriptor) && null == signature && null != exceptions && exceptions.length == 1 && Type.getInternalName(IOException.class).equals(exceptions[0]) && !this.skip.contains(OperationCategory.ZIP); }
From source file:de.zib.sfs.instrument.ZipFileAdapter.java
License:BSD License
private boolean isCloseMethod(int access, String name, String desc, String signature, String[] exceptions) { return Opcodes.ACC_PUBLIC == access && "close".equals(name) && desc.equals(Type.getMethodDescriptor(Type.VOID_TYPE)) && signature == null && exceptions != null && exceptions.length == 1 && Type.getInternalName(IOException.class).equals(exceptions[0]) && !this.skip.contains(OperationCategory.ZIP); }
From source file:dodola.anole.lib.ConstructorDelegationDetector.java
License:Apache License
/** * Splits the constructor in two methods, the "set up" and the "body" parts (see above). *//*from w ww. j ava 2 s . c o m*/ private static Constructor split(String owner, MethodNode method, VarInsnNode loadThis, MethodInsnNode delegation, int loadThisLine) { String[] exceptions = ((List<String>) method.exceptions).toArray(new String[method.exceptions.size()]); String newDesc = method.desc.replaceAll("\\((.*)\\)V", "([Ljava/lang/Object;$1)Ljava/lang/Object;"); MethodNode initArgs = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "init$args", newDesc, null, exceptions); AbstractInsnNode insn = loadThis.getNext(); while (insn != delegation) { insn.accept(initArgs); insn = insn.getNext(); } LabelNode labelBefore = new LabelNode(); labelBefore.accept(initArgs); GeneratorAdapter mv = new GeneratorAdapter(initArgs, initArgs.access, initArgs.name, initArgs.desc); // Copy the arguments back to the argument array // The init_args part cannot access the "this" object and can have side effects on the // local variables. Because of this we use the first argument (which we want to keep // so all the other arguments remain unchanged) as a reference to the array where to // return the values of the modified local variables. Type[] types = Type.getArgumentTypes(initArgs.desc); int stack = 1; // Skip the first one which is a reference to the local array. for (int i = 1; i < types.length; i++) { Type type = types[i]; // This is not this, but the array of local arguments final values. mv.visitVarInsn(Opcodes.ALOAD, 0); mv.push(i); mv.visitVarInsn(type.getOpcode(Opcodes.ILOAD), stack); mv.box(type); mv.arrayStore(Type.getType(Object.class)); stack += type.getSize(); } // Create the args array with the values to send to the delegated constructor Type[] returnTypes = Type.getArgumentTypes(delegation.desc); // The extra element for the qualified name of the constructor. mv.push(returnTypes.length + 1); mv.newArray(Type.getType(Object.class)); int args = mv.newLocal(Type.getType("[Ljava/lang/Object;")); mv.storeLocal(args); for (int i = returnTypes.length - 1; i >= 0; i--) { Type type = returnTypes[i]; mv.loadLocal(args); mv.swap(type, Type.getType(Object.class)); mv.push(i + 1); mv.swap(type, Type.INT_TYPE); mv.box(type); mv.arrayStore(Type.getType(Object.class)); } // Store the qualified name of the constructor in the first element of the array. mv.loadLocal(args); mv.push(0); mv.push(delegation.owner + "." + delegation.desc); // Name of the constructor to be called. mv.arrayStore(Type.getType(Object.class)); mv.loadLocal(args); mv.returnValue(); newDesc = method.desc.replace("(", "(L" + owner + ";"); MethodNode body = new MethodNode(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "init$body", newDesc, null, exceptions); LabelNode labelAfter = new LabelNode(); labelAfter.accept(body); Set<LabelNode> bodyLabels = new HashSet<LabelNode>(); insn = delegation.getNext(); while (insn != null) { if (insn instanceof LabelNode) { bodyLabels.add((LabelNode) insn); } insn.accept(body); insn = insn.getNext(); } // manually transfer the exception table from the existing constructor to the new // "init$body" method. The labels were transferred just above so we can reuse them. //noinspection unchecked for (TryCatchBlockNode tryCatch : (List<TryCatchBlockNode>) method.tryCatchBlocks) { tryCatch.accept(body); } //noinspection unchecked for (LocalVariableNode variable : (List<LocalVariableNode>) method.localVariables) { boolean startsInBody = bodyLabels.contains(variable.start); boolean endsInBody = bodyLabels.contains(variable.end); if (!startsInBody && !endsInBody) { if (variable.index != 0) { // '#0' on init$args is not 'this' variable.accept(initArgs); } } else if (startsInBody && endsInBody) { variable.accept(body); } else if (!startsInBody && endsInBody) { // The variable spans from the args to the end of the method, create two: if (variable.index != 0) { // '#0' on init$args is not 'this' LocalVariableNode var0 = new LocalVariableNode(variable.name, variable.desc, variable.signature, variable.start, labelBefore, variable.index); var0.accept(initArgs); } LocalVariableNode var1 = new LocalVariableNode(variable.name, variable.desc, variable.signature, labelAfter, variable.end, variable.index); var1.accept(body); } else { throw new IllegalStateException("Local variable starts after it ends."); } } return new Constructor(loadThis, loadThisLine, initArgs, delegation, body); }
From source file:dodola.anole.lib.IncrementalChangeVisitor.java
License:Apache License
/** * Generates new delegates for all 'patchable' methods in the visited class. Delegates * are static methods that do the same thing the visited code does, but from outside the class. * For instance methods, the instance is passed as the first argument. Note that: * <ul>/* w ww . j a v a 2 s.com*/ * <li>We ignore the class constructor as we don't support it right now</li> * <li>We skip abstract methods.</li> * <li>For constructors split the method body into super arguments and the rest of * the method body, see {@link ConstructorDelegationDetector}</li> * </ul> */ @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (instantRunDisabled || !isAccessCompatibleWithInstantRun(access)) { // Nothing to generate. return null; } if (name.equals("<clinit>")) { // we skip the class init as it can reset static fields which we don't support right now return null; } boolean isStatic = (access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(desc, isStatic); if (DEBUG) { System.out.println(">>> Visiting method " + visitedClassName + ":" + name + ":" + desc); if (exceptions != null) { for (String exception : exceptions) { System.out.println("> Exception thrown : " + exception); } } } if (DEBUG) { System.out.println("New Desc is " + newDesc + ":" + isStatic); } // Do not carry on any access flags from the original method. For example synchronized // on the original method would translate into a static synchronized method here. access = Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC; MethodNode method = getMethodByNameInClass(name, desc, classNode); if (name.equals("<init>")) { ConstructorDelegationDetector.Constructor constructor = ConstructorDelegationDetector .deconstruct(visitedClassName, method); MethodVisitor original = super.visitMethod(access, constructor.args.name, constructor.args.desc, constructor.args.signature, exceptions); ISVisitor mv = new ISVisitor(original, access, constructor.args.name, constructor.args.desc, isStatic, true /* isConstructor */); constructor.args.accept(mv); original = super.visitMethod(access, constructor.body.name, constructor.body.desc, constructor.body.signature, exceptions); mv = new ISVisitor(original, access, constructor.body.name, newDesc, isStatic, true /* isConstructor */); constructor.body.accept(mv); // Remember our created methods so we can generated the access$dispatch for them. addedMethods.add(constructor.args); addedMethods.add(constructor.body); return null; } else { String newName = isStatic ? computeOverrideMethodName(name, desc) : name; MethodVisitor original = super.visitMethod(access, newName, newDesc, signature, exceptions); return new ISVisitor(original, access, newName, newDesc, isStatic, false /* isConstructor */); } }
From source file:dodola.anole.lib.IncrementalChangeVisitor.java
License:Apache License
/** * To each class, add the dispatch method called by the original code that acts as a trampoline to * invoke the changed methods.//from www. java 2 s . c o m * <p/> * Pseudo code: * <code> * Object access$dispatch(String name, object[] args) { * if (name.equals( * "firstMethod.(L$type;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;")) { * return firstMethod(($type)arg[0], (String)arg[1], arg[2]); * } * if (name.equals("secondMethod.(L$type;Ljava/lang/String;I;)V")) { * secondMethod(($type)arg[0], (String)arg[1], (int)arg[2]); * return; * } * ... * StringBuilder $local1 = new StringBuilder(); * $local1.append("Method not found "); * $local1.append(name); * $local1.append(" in " + visitedClassName + * "$dispatch implementation, restart the application"); * throw new $package/InstantReloadException($local1.toString()); * } * </code> */ private void addDispatchMethod() { int access = Opcodes.ACC_PUBLIC | Opcodes.ACC_VARARGS; Method m = new Method("access$dispatch", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;"); MethodVisitor visitor = super.visitMethod(access, m.getName(), m.getDescriptor(), null, null); final GeneratorAdapter mv = new GeneratorAdapter(access, m, visitor); if (TRACING_ENABLED) { mv.push("Redirecting "); mv.loadArg(0); trace(mv, 2); } List<MethodNode> allMethods = new ArrayList<MethodNode>(); // if we are disabled, do not generate any dispatch, the method will throw an exception // if invoked which should never happen. if (!instantRunDisabled) { //noinspection unchecked allMethods.addAll(classNode.methods); allMethods.addAll(addedMethods); } final Map<String, MethodNode> methods = new HashMap<String, MethodNode>(); for (MethodNode methodNode : allMethods) { if (methodNode.name.equals("<clinit>") || methodNode.name.equals("<init>")) { continue; } if (!isAccessCompatibleWithInstantRun(methodNode.access)) { continue; } methods.put(methodNode.name + "." + methodNode.desc, methodNode); } new StringSwitch() { @Override void visitString() { mv.visitVarInsn(Opcodes.ALOAD, 1); } @Override void visitCase(String methodName) { MethodNode methodNode = methods.get(methodName); String name = methodNode.name; boolean isStatic = (methodNode.access & Opcodes.ACC_STATIC) != 0; String newDesc = computeOverrideMethodDesc(methodNode.desc, isStatic); if (TRACING_ENABLED) { trace(mv, "M: " + name + " P:" + newDesc); } Type[] args = Type.getArgumentTypes(newDesc); int argc = 0; for (Type t : args) { mv.visitVarInsn(Opcodes.ALOAD, 2); mv.push(argc); mv.visitInsn(Opcodes.AALOAD); ByteCodeUtils.unbox(mv, t); argc++; } mv.visitMethodInsn(Opcodes.INVOKESTATIC, visitedClassName + "$override", isStatic ? computeOverrideMethodName(name, methodNode.desc) : name, newDesc, false); Type ret = Type.getReturnType(methodNode.desc); if (ret.getSort() == Type.VOID) { mv.visitInsn(Opcodes.ACONST_NULL); } else { mv.box(ret); } mv.visitInsn(Opcodes.ARETURN); } @Override void visitDefault() { writeMissingMessageWithHash(mv, visitedClassName); } }.visit(mv, methods.keySet()); mv.visitMaxs(0, 0); mv.visitEnd(); super.visitEnd(); }