类型

正如在antlr 文件中定义的那样,我们扩充定义了一些基本的数据类型

primitiveType: 'boolean' ('[' ']')* |
'string' ('[' ']')*|
'char' ('[' ']')*|
'byte' ('[' ']')*|
'short' ('[' ']')*|
'int' ('[' ']')*|
'long' ('[' ']')*|
'float' ('[' ']')*|
'double' ('[' ']')*|
'void' ('[' ']')* ;

上述的定义表明我们支持使用一些基本的数据类型如intlong ,还支持对应数据的数组类型如int[] long[]

上面的类型如何被组装到字节码中的呢?

我们通过定义了一个类型的枚举类Type来映射每一个类型对应的descriptor

@Getter
@AllArgsConstructor
public enum Type {
BOOLEAN("boolean",boolean.class,"Z"),
INT("int", int.class,"I"),
CHAR ("char", char.class,"C"),
BYTE ("byte", byte.class,"B"),
SHORT ("short", short.class,"S"),
LONG ("long", long.class,"J"),
FLOAT ("float", float.class,"F"),
DOUBLE ("double", double.class,"D"),
STRING ("string", String.class,"Ljava/lang/String;"),
BOOLEAN_ARR("bool[]",boolean[].class,"[B"),
INT_ARR ("int[]", int[].class,"[I"),
CHAR_ARR ("char[]", char[].class,"[C"),
BYTE_ARR ("byte[]", byte[].class,"[B"),
SHORT_ARR ("short[]", short[].class,"[S"),
LONG_ARR ("long[]", long[].class,"[J"),
FLOAT_ARR ("float[]", float[].class,"[F"),
DOUBLE_ARR ("double[]", double[].class,"[D"),
STRING_ARR ("string[]", String[].class,"[Ljava/lang/String;"),
NONE("", null,""),
VOID("void", void.class,"V");
private final String name;
private final Class<?> typeClass;
private final String descriptor;
}

descriptor 是什么,它又在其中起了什么样的作用,JVM虚拟机规范中有一个简短的解释

1.1、字段描述符

标题为 1.1、字段描述符

一个字段描述符代表了一个类、实例或局部变量的类型,其中官方定义如下

描述符字段类型解释
Bbytesigned byte
CcharUnicode character code point in the Basic Multilingual Plane, encoded with UTF-16
Ddoubledouble-precision floating-point value
Ffloatsingle-precision floating-point value
Iintinteger
Jlonglong integer
LClassName ;reference an instance of class ClassName
Sshortsigned short
Zbooleantrue or false
[referenceone array dimension

主要的描述符类型有三种

  • 基本类型
  • 对象类型
  • 数组类型

我们暂时并不会实现多维数组,支持一个一维数组可以用来生成mainString[]参数就可以了,值得注意的是java支持数组维度的上限是255,如果你想支持多维数组的话,注意不要突破这个限制

1.2、方法描述符

标题为 1.2、方法描述符

一个方法描述符包含零个或多个参数描述符,代表该方法接受的参数类型,以及一个返回描述符,代表该方法返回值的类型(如果有的话),除了字段描述符已有的一些定义,方法描述符用V 来表示该方法不返回值

和数组维度的上限一样,方法参数的数量上限也是255