forked from burrowers/garble
/
ssa.go
43 lines (34 loc) · 1.12 KB
/
ssa.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
package ctrlflow
import (
"go/constant"
"go/types"
"reflect"
"unsafe"
"golang.org/x/tools/go/ssa"
)
// setUnexportedField is used to modify unexported fields of ssa api structures.
// TODO: find an alternative way to access private fields or raise a feature request upstream
func setUnexportedField(objRaw interface{}, name string, valRaw interface{}) {
obj := reflect.ValueOf(objRaw)
for obj.Kind() == reflect.Pointer || obj.Kind() == reflect.Interface {
obj = obj.Elem()
}
field := obj.FieldByName(name)
if !field.IsValid() {
panic("invalid field: " + name)
}
fakeStruct := reflect.NewAt(field.Type(), unsafe.Pointer(field.UnsafeAddr()))
fakeStruct.Elem().Set(reflect.ValueOf(valRaw))
}
func setBlockParent(block *ssa.BasicBlock, ssaFunc *ssa.Function) {
setUnexportedField(block, "parent", ssaFunc)
}
func setBlock(instr ssa.Instruction, block *ssa.BasicBlock) {
setUnexportedField(instr, "block", block)
}
func setType(instr ssa.Instruction, typ types.Type) {
setUnexportedField(instr, "typ", typ)
}
func makeSsaInt(i int) *ssa.Const {
return ssa.NewConst(constant.MakeInt64(int64(i)), types.Typ[types.Int])
}