/
constant_pool.go
83 lines (73 loc) · 2.2 KB
/
constant_pool.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
package heap
import (
"../../classfile"
"fmt"
)
type Constant interface {
}
// 运行时常量池
type ConstantPool struct {
class *Class
consts []Constant
}
func (self *ConstantPool) Name() string {
return self.class.name
}
/*
将class文件中的常量池转换成运行时常量池
*/
func newConstantPool(class *Class, cfCp classfile.ConstantPool) *ConstantPool {
// 获取常量池的长度
cpCount := len(cfCp)
consts := make([]Constant, cpCount)
// 常量池结构体
rtCp := &ConstantPool{class, consts}
// copy常量池
for i := 1; i < cpCount; i++ {
cpInfo := cfCp[i]
// 对于单数据位的直接提取常量池存到constas
// 对于两个数据位的索引需要特殊处理
switch cpInfo.(type) {
case *classfile.ConstantIntegerInfo:
intInfo := cpInfo.(*classfile.ConstantIntegerInfo)
consts[i] = intInfo.Value()
case *classfile.ConstantFloatInfo:
floatInfo := cpInfo.(*classfile.ConstantFloatInfo)
consts[i] = floatInfo.Value()
case *classfile.ConstantLongInfo:
longInfo := cpInfo.(*classfile.ConstantLongInfo)
consts[i] = longInfo.Value()
i++
case *classfile.ConstantDoubleInfo:
doubleInfo := cpInfo.(*classfile.ConstantDoubleInfo)
consts[i] = doubleInfo.Value()
i++
case *classfile.ConstantStringInfo:
stringInfo := cpInfo.(*classfile.ConstantStringInfo)
consts[i] = stringInfo.String()
case *classfile.ConstantClassInfo:
classInfo := cpInfo.(*classfile.ConstantClassInfo)
consts[i] = newClssRef(rtCp, classInfo)
case *classfile.ConstantFieldrefInfo:
fieldrefInfo := cpInfo.(*classfile.ConstantFieldrefInfo)
consts[i] = newFieldRef(rtCp, fieldrefInfo)
case *classfile.ConstantMethodrefInfo:
methodrefInfo := cpInfo.(*classfile.ConstantMethodrefInfo)
consts[i] = newMethodRef(rtCp, methodrefInfo)
case *classfile.ConstantInterfaceMethodrefInfo:
methodrefInfo := cpInfo.(*classfile.ConstantInterfaceMethodrefInfo)
consts[i] = newInterfaceMethodRef(rtCp, methodrefInfo)
}
}
return rtCp
}
/*
根据索引返回常量
*/
func (self *ConstantPool) GetConstant(index uint) Constant {
// 在Constant[index]中获取常量
if c := self.consts[index]; c != nil {
return c
}
panic(fmt.Sprintf("No constants at index %d", index))
}