ASM 字节码框架源码解析

Symbol解析

2019-02-10  本文已影响39人  Xcdf

1. Class 文件的基本结构

Class 文件结构:

ClassFile{  
    u4 magic;
    u2 minor_version;
    u2 major_version;
    u2 constant_pool_count;  
    cp_info constant_pool[constant_pool_count-1];  // *1*
    u2 access_flags;
    u2 this_class;
    u2 super_class;
    u2 interfaces_count;
    u2 interfaces[interfaces_count];
    u2 fields_count;
    field_info fields[fields_count];
    u2 methods_count;
    method_info methods[methods_count]; // *2*
    u2 attributes_count;
    attribute_info attributes[attributes_count]; // *3*
}

本节重点关注info[]数组结构。
1.cp_info
例如:CONSTANT_Intger_info 用来存储一个整数

CONSTANT_Intger_info{
    u1 tag;   //  tag==3
    u4 bytes; //  bytes使用4字节存储整型值
}

常量池中每一项常量都是一个表,共有11种结构【除去JDK 1.7之后的CONSTANT_InvokeDynamic和CONSTANT_InvokeDynamicTrans两个】,这11种表的第一位都是一个u1类型的标志位(Tag,1 ~ 12,缺少标志为2的数据类型),表示当前常量的类型

类型 tag 值 描述
CONSTANT_Utf8_info 1 UTF-8编码的字符串
CONSTANT_Integer_info 3 整型字面量
CONSTANT_Float_info 4 浮点型字面量
CONSTANT_Long_info 5 长整型字面量
CONSTANT_Double_info 6 双精度浮点型字面量
CONSTANT_Class_info 7 类或接口的符号引用
CONSTANT_String_info 8 字符串类型字面量
CONSTANT_Fieldref_info 9 字段的符号引用
CONSTANT_Methodref_info 10 类中方法的符号引用
CONSTANT_InterfaceMethodref_info 11 接口中方法的符号引用
CONSTANT_NameAndType_info 12 字段或方法的部分符号引用

2.method_info

3.attribute_info

2.Symbol 中的静态字段

// JVM 常量池中的项的tag值
static final int CONSTANT_UTF8_TAG = 1;  
static final int CONSTANT_INTEGER_TAG = 3;
static final int CONSTANT_FLOAT_TAG = 4;
static final int CONSTANT_LONG_TAG = 5;
static final int CONSTANT_DOUBLE_TAG = 6;
static final int CONSTANT_CLASS_TAG = 7;
static final int CONSTANT_STRING_TAG = 8;
static final int CONSTANT_FIELDREF_TAG = 9;
static final int CONSTANT_METHODREF_TAG = 10;
static final int CONSTANT_INTERFACE_METHODREF_TAG = 11;
static final int CONSTANT_NAME_AND_TYPE_TAG = 12;
static final int CONSTANT_METHOD_HANDLE_TAG = 15;
static final int CONSTANT_METHOD_TYPE_TAG = 16;
static final int CONSTANT_DYNAMIC_TAG = 17; 
static final int CONSTANT_INVOKE_DYNAMIC_TAG = 18;
static final int CONSTANT_MODULE_TAG = 19;
static final int CONSTANT_PACKAGE_TAG = 20;
static final int BOOTSTRAP_METHOD_TAG = 64;
// ASM 特殊tag
static final int TYPE_TAG = 128;
static final int UNINITIALIZED_TYPE_TAG = 129;
static final int MERGED_TYPE_TAG = 130;
  // 此符号在常量池、BootstrapMethods属性和类(ASM特定)类型表中的的索引
  final int index;

  // 此符号的tag值
  final int tag;

  // 此符号的所有者类的内部名称,形如:java/lang/String
  final String owner;

  // 与此符号对应的字段或方法的名称
  final String name;

  // 此个符号的值
  final String value;

  // 此符号的数值
  final long data;

  // 有关此符号的其他信息
  int info;

  // 构造一个新的Symbol对象。 此构造函数不能直接使用,因为Symbol类是抽象类。 而是使用SymbolTable类的工厂方法。
  Symbol(
      final int index,
      final int tag,
      final String owner,
      final String name,
      final String value,
      final long data) {
    this.index = index;
    this.tag = tag;
    this.owner = owner;
    this.name = name;
    this.value = value;
    this.data = data;
  }
 // 返回结果
  int getArgumentsAndReturnSizes() {
    if (info == 0) {
      info = Type.getArgumentsAndReturnSizes(value);
    }
    return info;
  }

3.Symbol 的使用

private static class Entry extends Symbol {
此类相当于一个节点,用来表示cp_info[] method_info[], attribute_info[] 的节点。

上一篇 下一篇

猜你喜欢

热点阅读