List of usage examples for org.objectweb.asm Opcodes ACC_STATIC
int ACC_STATIC
To view the source code for org.objectweb.asm Opcodes ACC_STATIC.
Click Source Link
From source file:ca.weblite.mirah.ant.mirrors.ClassReader.java
/** * Generates the the mirah mirrors for a specific java source file. This * file must be a .java file. It cannot be a directory. * //from w ww. java 2s. co m * @param javaSourceFile * @throws IOException */ public void parse() throws IOException { File javaSourceFile = sourceFile; JavaCompiler compiler = JavacTool.create(); MyFileObject[] fos = new MyFileObject[] { new MyFileObject(javaSourceFile) }; JavacTask task = (JavacTask) compiler.getTask(null, null, null, null, null, Arrays.asList(fos)); Iterable<? extends CompilationUnitTree> asts = task.parse(); final Stack<Set<String>> typeParams = new Stack<Set<String>>(); TreePathScanner scanner; scanner = new TreePathScanner() { private boolean isGenericType(String type) { Stack<Set> desk = new Stack<Set>(); boolean found = false; while (!typeParams.empty()) { Set params = typeParams.pop(); desk.push(params); if (params.contains(type)) { found = true; break; } } while (!desk.empty()) { typeParams.push(desk.pop()); } return found; } String formatType(String type) { int pos = type.indexOf("<"); if (pos >= 0) { type = type.substring(0, pos); } if (isGenericType(type)) { return "Object"; } return type; } @Override public Object visitCompilationUnit(CompilationUnitTree cut, Object p) { PackageScope scope = new PackageScope(scopeStack.peek(), cut.getPackageName().toString()); scope.addImport(scope.getPackageName() + ".*"); scope.addImport("java.lang.*"); scope.addImport("*"); packageScope = scope; scopeStack.push(scope); return super.visitCompilationUnit(cut, p); } @Override public Object visitImport(ImportTree it, Object p) { String path = it.getQualifiedIdentifier().toString(); packageScope.addImport(path); return super.visitImport(it, p); } private void decorateClassNode(ClassTree ct, ClassNode classNode) { int flags = getFlags(ct.getModifiers().getFlags()); switch (ct.getKind()) { case INTERFACE: flags |= Opcodes.ACC_INTERFACE; break; case ENUM: flags |= Opcodes.ACC_ENUM; break; } classNode.access = flags; classNode.sourceFile = sourceFile.getPath(); String extendsClause = "java.lang.Object"; if (ct.getExtendsClause() != null) { extendsClause = ct.getExtendsClause().toString(); } String superPath = scopeStack.peek().resolveName(extendsClause, false); ClassIndex.Node superNode = scopeStack.peek().getLoader().find(superPath); if (superNode == null) { throw new RuntimeException("Failed to find super class " + superPath); } classNode.superName = superNode.internalName; classNode.interfaces = new ArrayList<String>(); String impl = ct.getImplementsClause().toString(); if (!"".equals(impl)) { String[] interfaces = impl.split(","); for (String iface : interfaces) { iface = iface.trim(); String ipath = scopeStack.peek().resolveName(iface, false); ClassIndex.Node iNode = scopeStack.peek().getLoader().find(ipath); if (iNode == null) { throw new RuntimeException("Failed to load " + "interface " + ipath); } classNode.interfaces.add(iNode.internalName); } } } @Override public Object visitClass(ClassTree ct, Object p) { ClassScope clsScope = null; ClassNode currClassNode = null; if (scopeStack.peek() == packageScope) { String path = packageScope.getPackageName() + "." + ct.getSimpleName(); ClassIndex.Node n = packageScope.getLoader().find(path); if (n == null) { throw new RuntimeException("Failed to find class " + path); } node.name = n.internalName; currClassNode = node; decorateClassNode(ct, node); clsScope = new ClassScope(scopeStack.peek(), n); } else { // This must be an internal class ClassNode parentClass = classNodeStack.peek(); if (parentClass.innerClasses == null) { parentClass.innerClasses = new ArrayList<>(); } String path = scopeStack.peek().resolveName(ct.getSimpleName().toString(), false); ClassIndex.Node n = packageScope.getLoader().find(path); if (n == null) { throw new RuntimeException("Failed to find class " + path); } InnerClassNode innerNode = new InnerClassNode(n.internalName, parentClass.name, n.simpleName, getFlags(ct.getModifiers().getFlags())); parentClass.innerClasses.add(innerNode); ClassNode cls = new ClassNode(); cls.name = n.internalName; cls.outerClass = parentClass.name; decorateClassNode(ct, cls); clsScope = new ClassScope(scopeStack.peek(), n); currClassNode = cls; } scopeStack.push(clsScope); classNodeStack.push(currClassNode); Object out = super.visitClass(ct, p); classNodeStack.pop(); scopeStack.pop(); return out; } /** * Converts modifier flags from Javac Tree into int flags usable in * TypeMirror * @param mods * @return */ int getFlags(Set<Modifier> mods) { int flags = 0; for (Modifier m : mods) { switch (m) { case ABSTRACT: flags |= Opcodes.ACC_ABSTRACT; break; case FINAL: flags |= Opcodes.ACC_FINAL; break; case PRIVATE: flags |= Opcodes.ACC_PRIVATE; break; case PROTECTED: flags |= Opcodes.ACC_PROTECTED; break; case PUBLIC: flags |= Opcodes.ACC_PUBLIC; break; case STATIC: flags |= Opcodes.ACC_STATIC; break; } } return flags; } @Override public Object visitVariable(final VariableTree vt, Object p) { String typeName = vt.getType().toString(); String typePath = scopeStack.peek().resolveName(vt.getType().toString(), false); String typeDescriptor = scopeStack.peek().resolveName(vt.getType().toString(), true); String name = vt.getName().toString(); int flags = getFlags(vt.getModifiers().getFlags()); FieldNode fieldNode = new FieldNode(flags, name, typeDescriptor, null, null); ClassNode cls = classNodeStack.peek(); if (cls.fields == null) { cls.fields = new ArrayList<FieldNode>(); } cls.fields.add(fieldNode); return super.visitVariable(vt, p); } String generateMethodDescriptor(MethodTree mt) { StringBuilder sb = new StringBuilder(); sb.append("("); for (VariableTree v : mt.getParameters()) { String type = scopeStack.peek().resolveName(v.getType().toString(), true); sb.append(type); } sb.append(")"); String returnType = scopeStack.peek().resolveName(mt.getReturnType().toString(), true); sb.append(returnType); return sb.toString(); } @Override public Object visitMethod(final MethodTree mt, Object p) { MethodNode m = new MethodNode(); int flags = getFlags(mt.getModifiers().getFlags()); m.access = flags; m.desc = generateMethodDescriptor(mt); m.name = mt.getName().toString(); ClassNode cls = classNodeStack.peek(); if (cls.methods == null) { cls.methods = new ArrayList<MethodNode>(); } cls.methods.add(m); return mt; } }; scanner.scan(asts, null); }
From source file:ca.weblite.mirah.ant.mirrors.ClassReaderTest.java
@Test public void testParseClass() throws IOException { ClassNode node = new ClassNode(); ResourceLoader loader = new ResourceLoader(); System.out.println(System.getProperties()); loader.setClassPath(System.getProperty("sun.boot.class.path") + File.pathSeparator + System.getProperty("java.class.path")); loader.setJavaSourcePath("test"); File file = new File("test/ca/weblite/mirah/ant/mirrors/SampleJavaClass.java"); loader.fillIndex();/* w w w. j a v a 2s. c o m*/ assertTrue("java.util.Map not found", loader.find("java.util.Map") != null); ClassReader reader = new ClassReader(node, file, loader); reader.parse(); assertEquals("Class name is incorrect", "ca/weblite/mirah/ant/mirrors/SampleJavaClass", node.name); boolean foundSomeField = false; boolean foundObjField = false; boolean foundPrivateField = false; boolean foundPublicField = false; boolean foundProtectedField = false; for (Object o : node.fields) { FieldNode n = (FieldNode) o; System.out.println("Field " + n.name + " desc " + n.desc); if ("someField".equals(n.name) && "I".equals(n.desc)) { foundSomeField = true; } if ("someObjField".equals(n.name) && "Ljava/lang/Object;".equals(n.desc)) { foundObjField = true; assertTrue("someObjeField is not public", ((n.access & Opcodes.ACC_PUBLIC) == 0)); assertTrue("someObjeField is not private", ((n.access & Opcodes.ACC_PRIVATE) == 0)); assertTrue("someObjeField is not protected", ((n.access & Opcodes.ACC_PROTECTED) == 0)); assertTrue("someObjeField is not abstract", ((n.access & Opcodes.ACC_ABSTRACT) == 0)); assertTrue("someObjeField is not static", ((n.access & Opcodes.ACC_STATIC) == 0)); } if ("privateField".equals(n.name) && "Ljava/lang/Object;".equals(n.desc)) { foundPrivateField = true; assertTrue("privateField is not public", ((n.access & Opcodes.ACC_PUBLIC) == 0)); assertTrue("privateField should be private", ((n.access & Opcodes.ACC_PRIVATE) != 0)); assertTrue("privateField is not protected", ((n.access & Opcodes.ACC_PROTECTED) == 0)); assertTrue("privateField is not abstract", ((n.access & Opcodes.ACC_ABSTRACT) == 0)); assertTrue("privateField is not static", ((n.access & Opcodes.ACC_STATIC) == 0)); } if ("protectedField".equals(n.name) && "Ljava/lang/Object;".equals(n.desc)) { foundProtectedField = true; assertTrue("protectedField should not public", ((n.access & Opcodes.ACC_PUBLIC) == 0)); assertTrue("protectedField should not be private", ((n.access & Opcodes.ACC_PRIVATE) == 0)); assertTrue("protectedField should be protected", ((n.access & Opcodes.ACC_PROTECTED) != 0)); assertTrue("protectedField should not be abstract", ((n.access & Opcodes.ACC_ABSTRACT) == 0)); assertTrue("protectedField should not static", ((n.access & Opcodes.ACC_STATIC) == 0)); } if ("publicField".equals(n.name) && "Ljava/lang/Object;".equals(n.desc)) { foundPublicField = true; assertTrue("publicField should be public", ((n.access & Opcodes.ACC_PUBLIC) != 0)); assertTrue("publicField should not be private", ((n.access & Opcodes.ACC_PRIVATE) == 0)); assertTrue("publicField should not be protected", ((n.access & Opcodes.ACC_PROTECTED) == 0)); assertTrue("publicField should not be abstract", ((n.access & Opcodes.ACC_ABSTRACT) == 0)); assertTrue("publicField should not static", ((n.access & Opcodes.ACC_STATIC) == 0)); } } assertTrue("someField was not found", foundSomeField); assertTrue("object field was not found", foundObjField); assertTrue("private field was not found", foundPrivateField); assertTrue("public field was not found", foundPublicField); assertTrue("protected field was not found", foundProtectedField); }
From source file:ch.eiafr.cojac.Agent.java
License:Apache License
/** * This method works only with the FloatReplacerClasses class * It instruments it to create a static initializer block to set * all the static variables used by the agent and injected in the * instrumented application./*from w ww. j av a2s . c o m*/ * Warning: this is not the only place to set these variables, see class * "CojacReferences" ! * This is used when there is more than one classloader in the application */ private byte[] setGlobalFields(byte[] byteCode, ClassLoader loader) { ClassReader cr = new ClassReader(byteCode); ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = new ClassVisitor(Opcodes.ASM5, cw) { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); MethodVisitor mv = cv.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null); mv.visitLdcInsn(references.getDoubleWrapper()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setNgWrapper", "(Ljava/lang/String;)V", false); mv.visitLdcInsn(references.getNgWrapper()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setDoubleWrapper", "(Ljava/lang/String;)V", false); mv.visitLdcInsn(references.getFloatWrapper()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setFloatWrapper", "(Ljava/lang/String;)V", false); mv.visitLdcInsn(references.getBigDecimalPrecision()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setBigDecimalPrecision", "(I)V", false); mv.visitLdcInsn(references.getStabilityThreshold()); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setStabilityThreshold", "(D)V", false); mv.visitLdcInsn(references.getCheckUnstableComparisons() ? 1 : 0); mv.visitMethodInsn(Opcodes.INVOKESTATIC, name, "setCheckUnstableComparisons", "(Z)V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); } }; cr.accept(cv, ClassReader.EXPAND_FRAMES); return cw.toByteArray(); }
From source file:ch.eiafr.cojac.FloatVariablesSorter.java
License:Apache License
public FloatVariablesSorter(int access, String oldDesc, AnalyzerAdapter mv) { super(Opcodes.ASM5, mv); Type[] args = Type.getArgumentTypes(oldDesc); firstFrameMapping = new int[1 + args.length * 2]; // +1 for 'this' Arrays.fill(firstFrameMapping, -1); // so that erroneously using unwritten cells will cause problems... boolean hasTarget = (Opcodes.ACC_STATIC & access) == 0; // not static -> there is a 'this' param int oldVarIndex = 0; int newVarIndex = 0; int lastIndexSet = -1; if (hasTarget) { oldVarIndex = newVarIndex = 1;//from w ww. java 2 s . c o m firstFrameMapping[0] = 0; // 'this' remains 'this' after remapping... lastIndexSet = 0; } for (Type arg : args) { firstFrameMapping[oldVarIndex] = newVarIndex; lastIndexSet = oldVarIndex; oldVarIndex += arg.getSize(); newVarIndex += arg.getSize(); if (arg.equals(Type.DOUBLE_TYPE)) { newVarIndex--; } assert !arg.equals(COJAC_DOUBLE_WRAPPER_TYPE); // this would be strange (the descriptor is the old one) } maxRenumber = lastIndexSet; }
From source file:cl.inria.stiq.instrumenter.BCIUtils.java
License:Open Source License
public static boolean isStatic(int access) { return (access & Opcodes.ACC_STATIC) != 0; }
From source file:Client.JClassPatcher.java
License:Open Source License
private String decodeAccess(int access) { String res = ""; if ((access & Opcodes.ACC_PUBLIC) == Opcodes.ACC_PUBLIC) res += "public "; if ((access & Opcodes.ACC_PRIVATE) == Opcodes.ACC_PRIVATE) res += "private "; if ((access & Opcodes.ACC_PROTECTED) == Opcodes.ACC_PROTECTED) res += "protected "; if ((access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC) res += "static "; if ((access & Opcodes.ACC_FINAL) == Opcodes.ACC_FINAL) res += "final "; if ((access & Opcodes.ACC_VOLATILE) == Opcodes.ACC_VOLATILE) res += "protected "; if ((access & Opcodes.ACC_SYNCHRONIZED) == Opcodes.ACC_SYNCHRONIZED) res += "synchronized "; if ((access & Opcodes.ACC_ABSTRACT) == Opcodes.ACC_ABSTRACT) res += "abstract "; if ((access & Opcodes.ACC_INTERFACE) == Opcodes.ACC_INTERFACE) res += "interface "; return res;// w w w . j a v a 2s.c o m }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //This method is a little bit complicated. //We need to generate a delegate class implementing NetworkCallDelegate and a redirect //the code that originally generated here in parent, into the delegate class, //by returning a MethodVisitor under the ClassVisitor of the delegate class. //Besides, we should generate a call to NetworkCallManager into parent. //Above is the original method. Now it has a little bit change. To allow private call in //here, we need to generate the delegate method in this class instead of in a delegate class. //We make the delegate method public so that the delegate class can call it. //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(desc); final Type ret = Type.getReturnType(desc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. in method " + methodName + ", " + t.getDescriptor()); }// w w w.j a v a 2s .c o m } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //array size parent.visitTypeInsn(Opcodes.ANEWARRAY, Type.getInternalName(Object.class)); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(String.class), Type.getType(Object[].class))); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateFunctionName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), //changed to original class className.replace('.', '/'), delegateFunctionName, desc); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // xxxx.xxxx_delegated_xxx((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateFunctionName, desc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; double sendRange = -1; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } } @Override public AnnotationVisitor visitParameterAnnotation(final int parameter, String desc, boolean visible) { Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } range = null; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:cn.annoreg.asm.DelegateGenerator.java
License:Open Source License
public static MethodVisitor generateNonStaticMethod(ClassVisitor parentClass, MethodVisitor parent, String className, String methodName, String desc, final Side side) { //convert desc to a non-static method form String nonstaticDesc;/* w w w . jav a 2 s . c om*/ { Type staticType = Type.getMethodType(desc); Type retType = staticType.getReturnType(); Type[] argsType = staticType.getArgumentTypes(); Type[] argsTypeWithThis = new Type[argsType.length + 1]; argsTypeWithThis[0] = Type.getType('L' + className.replace('.', '/') + ';'); System.arraycopy(argsType, 0, argsTypeWithThis, 1, argsType.length); nonstaticDesc = Type.getMethodDescriptor(retType, argsTypeWithThis); } //delegateName is a string used by both sides to identify a network-call delegate. final String delegateName = className + ":" + methodName + ":" + desc; final Type[] args = Type.getArgumentTypes(nonstaticDesc); final Type ret = Type.getReturnType(nonstaticDesc); //Check types for (Type t : args) { //TODO support these types if (!t.getDescriptor().startsWith("L") && !t.getDescriptor().startsWith("[")) { throw new RuntimeException("Unsupported argument type in network call. "); } } if (!ret.equals(Type.VOID_TYPE)) { throw new RuntimeException( "Unsupported return value type in network call. " + "Only void is supported."); } //Generate call to NetworkCallManager in parent. parent.visitCode(); //First parameter parent.visitLdcInsn(delegateName); //Second parameter: object array pushIntegerConst(parent, args.length); //this (0) has been included parent.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object"); for (int i = 0; i < args.length; ++i) { parent.visitInsn(Opcodes.DUP); pushIntegerConst(parent, i); parent.visitVarInsn(Opcodes.ALOAD, i); parent.visitInsn(Opcodes.AASTORE); } //Call cn.annoreg.mc.network.NetworkCallManager.onNetworkCall parent.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(NetworkCallManager.class), "onNetworkCall", "(Ljava/lang/String;[Ljava/lang/Object;)V"); parent.visitInsn(Opcodes.RETURN); parent.visitMaxs(5, args.length); parent.visitEnd(); //Create delegate object. final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); final String delegateId = Integer.toString(delegateNextID++); final Type delegateClassType = Type.getType("cn/annoreg/asm/NetworkCallDelegate_" + delegateId); cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, delegateClassType.getInternalName(), null, Type.getInternalName(Object.class), new String[] { Type.getInternalName(NetworkCallDelegate.class) }); //package cn.annoreg.asm; //class NetworkCallDelegate_? implements NetworkCallDelegate { { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } //public NetworkCallDelegate_?() {} final String delegateMethodName = methodName + "_delegate_" + delegateId; { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "invoke", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(Object[].class)), null, null); mv.visitCode(); //check if this is null mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, 0); mv.visitInsn(Opcodes.AALOAD); Label lblEnd = new Label(); mv.visitJumpInsn(Opcodes.IFNULL, lblEnd); for (int i = 0; i < args.length; ++i) { mv.visitVarInsn(Opcodes.ALOAD, 1); //0 is this pushIntegerConst(mv, i); mv.visitInsn(Opcodes.AALOAD); mv.visitTypeInsn(Opcodes.CHECKCAST, args[i].getInternalName()); } mv.visitMethodInsn(Opcodes.INVOKESTATIC, //delegateClassType.getInternalName(), className.replace('.', '/'), delegateMethodName, nonstaticDesc); mv.visitLabel(lblEnd); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(args.length + 2, 2); mv.visitEnd(); } //@Override public void invoke(Object[] args) { // delegated((Type0) args[0], (Type1) args[1], ...); //} //The returned MethodVisitor will visit the original version of the method, //including its annotation, where we can get StorageOptions. return new MethodVisitor(Opcodes.ASM4, parentClass.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, delegateMethodName, nonstaticDesc, null, null)) { //Remember storage options for each argument StorageOption.Option[] options = new StorageOption.Option[args.length]; int targetIndex = -1; double sendRange = -1; StorageOption.Target.RangeOption range = StorageOption.Target.RangeOption.SINGLE; { for (int i = 0; i < options.length; ++i) { options[i] = StorageOption.Option.NULL; //set default value } options[0] = StorageOption.Option.INSTANCE; } @Override public AnnotationVisitor visitParameterAnnotation(int parameter_in_func, String desc, boolean visible) { final int parameter = parameter_in_func + 1; //skip this Type type = Type.getType(desc); if (type.equals(Type.getType(StorageOption.Data.class))) { options[parameter] = StorageOption.Option.DATA; } else if (type.equals(Type.getType(StorageOption.Instance.class))) { //INSTANCE as defualt options[parameter] = StorageOption.Option.INSTANCE; //Change to NULLABLE_INSTANCE if nullable set to true return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { if (name.equals("nullable")) { if ((Boolean) value == true) { options[parameter] = StorageOption.Option.NULLABLE_INSTANCE; } } super.visit(name, value); } }; } else if (type.equals(Type.getType(StorageOption.Update.class))) { options[parameter] = StorageOption.Option.UPDATE; } else if (type.equals(Type.getType(StorageOption.Null.class))) { options[parameter] = StorageOption.Option.NULL; } else if (type.equals(Type.getType(StorageOption.Target.class))) { if (!args[parameter].equals(Type.getType(EntityPlayer.class))) { throw new RuntimeException("Target annotation can only be used on EntityPlayer."); } if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } options[parameter] = StorageOption.Option.INSTANCE; targetIndex = parameter; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visitEnum(String name, String desc, String value) { super.visitEnum(name, desc, value); range = StorageOption.Target.RangeOption.valueOf(value); } }; } else if (type.equals(Type.getType(StorageOption.RangedTarget.class))) { if (targetIndex != -1) { throw new RuntimeException("You can not specify multiple targets."); } targetIndex = parameter; range = null; return new AnnotationVisitor(this.api, super.visitParameterAnnotation(parameter, desc, visible)) { @Override public void visit(String name, Object value) { super.visit(name, value); sendRange = (double) value; } }; } return super.visitParameterAnnotation(parameter, desc, visible); } //TODO this option (from annotation) @Override public void visitEnd() { super.visitEnd(); //This is the last method in the delegate class. //Finish the class and do the registration. cw.visitEnd(); try { Class<?> clazz = classLoader.defineClass(delegateClassType.getClassName(), cw.toByteArray()); NetworkCallDelegate delegateObj = (NetworkCallDelegate) clazz.newInstance(); if (side == Side.CLIENT) { NetworkCallManager.registerClientDelegateClass(delegateName, delegateObj, options, targetIndex, range, sendRange); } else { NetworkCallManager.registerServerDelegateClass(delegateName, delegateObj, options); } } catch (Throwable e) { throw new RuntimeException("Can not create delegate for network call.", e); } } }; //public static void delegated(Type0 arg0, Type1, arg1, ...) { // //Code generated by caller. //} //} }
From source file:cn.annoreg.asm.NetworkCallTransformer.java
License:Open Source License
@Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { for (ClassMethod m : methods) { if (m.name == name && m.desc == desc) { switch (access & Opcodes.ACC_STATIC) { case Opcodes.ACC_STATIC: return DelegateGenerator.generateStaticMethod(this, super.visitMethod(access, name, desc, signature, exceptions), className, name, desc, m.side);//from w w w . j av a2s . c o m default: return DelegateGenerator.generateNonStaticMethod(this, super.visitMethod(access, name, desc, signature, exceptions), className, name, desc, m.side); } } } //Not found return super.visitMethod(access, name, desc, signature, exceptions); }
From source file:cn.edu.sjtu.se.yudiZheng.UnreachableCodeDetector.java
License:Open Source License
public void visitClassContext(ClassContext classContext) { ClassReader cr = new ClassReader(classContext.getJavaClass().getBytes()); ClassNode cn = new ClassNode(); cr.accept(cn, ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES); for (MethodNode method : (List<MethodNode>) cn.methods) { CtrlFlowGraph cfg = CtrlFlowGraph.build(method); List<BasicBlock> connected = new LinkedList<BasicBlock>(cfg.getNodes()); connected.remove(cfg.getBB(method.instructions.getFirst())); for (TryCatchBlockNode tcb : (List<TryCatchBlockNode>) method.tryCatchBlocks) { connected.remove(cfg.getBB(tcb.handler)); }/*from w w w . jav a 2 s.c o m*/ for (BasicBlock bb : connected) { if (bb.getPredecessors().size() == 0) { reporter.reportBug(new BugInstance(this, "UNREACHABLE", NORMAL_PRIORITY).addClass(cn).addMethod( cn.name, method.name, method.desc, (method.access & Opcodes.ACC_STATIC) != 0)); } } } }