zoukankan      html  css  js  c++  java
  • Proj. THUIoTFuzz: Java库-ASM#2

    Generics

    为了向后兼容,关于泛型的信息并不是直接存在type或者method descriptors中的,而是存在type, method和class signatures中。而这些signatures是存在class/field/method declarations中的。编译器会使用这些信息做静态类型检查,不过编译的时候不会使用这些信息,具体运行的时候也是使用type casts或者reflection来实现的。

    Type signature

    基本规则如下:

    示例:

    Method Signature

    示例:

    Class Signature

    SignatureVisitor

    执行顺序

    基本方法还是SignatureReader->SignatureVisitor->SignatureWriter

    例子


    Annotation

    如果Annotation的retention policy不是RetentionPolicy.Source,那么annotations都会存在compiled class中,可以通过reflection API获取。
    Annotations在源代码中可能有多种形式,比如@Deprecated,或者@Retention(RetentionPolicy.CLASS)等。不过,几乎所有的annotations是以一个annotation type开头,后面跟着一串name value对,而value只能是: 1. primitive, Class, String
    2. enum
    3. annotation values//annotation能够嵌套其他的annotation
    4. arrays of the above values

    AnnotationVisitor


    执行顺序

    例子-删除annotation

    很简单,在ClassVisitor执行visitAnnotation返回null即可。

    例子-添加annotation

    所有的在visitAnnotation之后的方法都需要重载来确认确实添加了Annotation。

    Debug

    使用javac -g编译出来的classes会包含调试信息,主要就是包含sourcefile的名称,line numbers等。
    ASM提供了visitSource, visitLineNumber, visitLocalVariable(获取具体variable names)

    Tree API

    ClassNode是ClassVisitor的一种,不过通过ClassNode有机会非线性访问数据。

    基本使用模式

      ClassReader classReader = new ClassReader(source);
      ClassNode classNode = new ClassNode();
      classReader.accept(classNode, 0);
    
      ClassWriter classWriter = new ClassWriter(0);
      classNode.accept(classWriter);
    
      ClassReader classReader = new ClassReader(source);
      ClassWriter classWriter = new ClassWriter(0);
      ClassVisitor classVisitor = new ClassVisitor(ASM7, classWriter) {
        public MethodVisitor visitMethod(int access, String name,
            String desc, String signature, String[] exceptions) {
          final MethodVisitor methodVisitor = 
              super.visitMethod(access, name, desc, signature, exceptions);
          MethodNode methodNode = new MethodNode(access, name, desc, signature, exceptions) {
            public void visitEnd() {
              // transform or analyze method code using tree API
              accept(methodVisitor);
            }
          };
        }
      };
      classReader.accept(classVisitor, 0);
    

    操作指令

    第一种,线性添加

    MethodNode methodNode = new MethodNode(...);
    methodNode.instructions.add(new VarInsnNode(ALOAD, 0));
    

    或者

    MethodNode methodNode = new MethodNode(...);
    methodNode.visitVarInsn(ALOAD, 0);
    

    第二种,使用记录下来的AbstractInsnNode来添加

    MethodNode methodNode = new MethodNode(...);
    methodNode.visitVarInsn(ALOAD, 0);
    AbstractInsnNode ptr = methodNode.instructions.getLast();
    methodNode.visitVarInsn(ALOAD, 1);
    // inserts an instruction between ALOAD 0 and ALOAD 1
    methodNode.instructions.insert(ptr, new VarInsnNode(ALOAD, 0));
    ...
    
  • 相关阅读:
    1061 Dating (20 分)
    1112 Stucked Keyboard (20 分)
    1077 Kuchiguse (20 分)
    1065 A+B and C (64bit) (20 分)
    1046 Shortest Distance (20 分)
    1124 Raffle for Weibo Followers (20 分)
    1036 Boys vs Girls (25 分)
    1113 Integer Set Partition (25 分)
    f开头的
    g开头的
  • 原文地址:https://www.cnblogs.com/xuesu/p/14136567.html
Copyright © 2011-2022 走看看