diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-05-05 10:13:04 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-05-05 10:13:04 +0200 |
| commit | 9dfb5efa91fc0f051a1ddc88ace2867bb6b32275 (patch) | |
| tree | 6957d2852c869a559d1127d297d80ffc191ae292 /prog/prog.go | |
| parent | 5ca897bd501e4b9a3a1b130bc9ec95243a4804a0 (diff) | |
prog: simplify code
Now that we don't have ReturnArg and only ResultArg's refer
to other ResultArg's we can remove ArgUser/ArgUsed and
devirtualize lots of code.
Diffstat (limited to 'prog/prog.go')
| -rw-r--r-- | prog/prog.go | 79 |
1 files changed, 25 insertions, 54 deletions
diff --git a/prog/prog.go b/prog/prog.go index 1bec61643..ef09d46a9 100644 --- a/prog/prog.go +++ b/prog/prog.go @@ -15,7 +15,7 @@ type Prog struct { type Call struct { Meta *Syscall Args []Arg - Ret Arg + Ret *ResultArg } type Arg interface { @@ -23,24 +23,6 @@ type Arg interface { Size() uint64 } -// ArgUser is interface of an argument that uses value of another output argument. -type ArgUser interface { - Uses() *Arg -} - -// ArgUsed is interface of an argument that can be used by other arguments. -type ArgUsed interface { - Used() *map[Arg]bool -} - -func isUsed(arg Arg) bool { - used, ok := arg.(ArgUsed) - if !ok { - return false - } - return len(*used.Used()) != 0 -} - type ArgCommon struct { typ Type } @@ -259,23 +241,22 @@ func (arg *UnionArg) Size() uint64 { // Either holds constant value or reference another ResultArg. type ResultArg struct { ArgCommon - Res Arg // reference to arg which we use - OpDiv uint64 // divide result (executed before OpAdd) - OpAdd uint64 // add to result - Val uint64 // value used if Res is nil - uses map[Arg]bool // ArgResult args that use this arg + Res *ResultArg // reference to arg which we use + OpDiv uint64 // divide result (executed before OpAdd) + OpAdd uint64 // add to result + Val uint64 // value used if Res is nil + uses map[*ResultArg]bool // ArgResult args that use this arg } -func MakeResultArg(t Type, r Arg, v uint64) *ResultArg { +func MakeResultArg(t Type, r *ResultArg, v uint64) *ResultArg { arg := &ResultArg{ArgCommon: ArgCommon{typ: t}, Res: r, Val: v} if r == nil { return arg } - used := r.(ArgUsed) - if *used.Used() == nil { - *used.Used() = make(map[Arg]bool) + if r.uses == nil { + r.uses = make(map[*ResultArg]bool) } - (*used.Used())[arg] = true + r.uses[arg] = true return arg } @@ -291,14 +272,6 @@ func (arg *ResultArg) Size() uint64 { return arg.typ.Size() } -func (arg *ResultArg) Used() *map[Arg]bool { - return &arg.uses -} - -func (arg *ResultArg) Uses() *Arg { - return &arg.Res -} - // Returns inner arg for pointer args. func InnerArg(arg Arg) Arg { if t, ok := arg.Type().(*PtrType); ok { @@ -479,36 +452,34 @@ func replaceArg(arg, arg1 Arg) { func replaceResultArg(arg, arg1 *ResultArg) { // Remove link from `a.Res` to `arg`. if arg.Res != nil { - delete(*arg.Res.(ArgUsed).Used(), arg) + delete(arg.Res.uses, arg) } // Copy all fields from `arg1` to `arg` except for the list of args that use `arg`. - used := *arg.Used() + uses := arg.uses *arg = *arg1 - *arg.Used() = used + arg.uses = uses // Make the link in `arg.Res` (which is now `Res` of `arg1`) to point to `arg` instead of `arg1`. if arg.Res != nil { - delete(*arg.Res.(ArgUsed).Used(), arg1) - (*arg.Res.(ArgUsed).Used())[arg] = true + resUses := arg.Res.uses + delete(resUses, arg1) + resUses[arg] = true } } // removeArg removes all references to/from arg0 from a program. func removeArg(arg0 Arg) { ForeachSubArg(arg0, func(arg Arg, ctx *ArgCtx) { - if a, ok := arg.(*ResultArg); ok && a.Res != nil { - if !(*a.Res.(ArgUsed).Used())[arg] { - panic("broken tree") - } - delete(*a.Res.(ArgUsed).Used(), arg) - } - if used, ok := arg.(ArgUsed); ok { - for arg1 := range *used.Used() { - a1, ok := arg1.(*ResultArg) - if !ok { - panic("use references not ArgResult") + if a, ok := arg.(*ResultArg); ok { + if a.Res != nil { + uses := a.Res.uses + if !uses[a] { + panic("broken tree") } + delete(uses, a) + } + for arg1 := range a.uses { arg2 := MakeResultArg(arg1.Type(), nil, arg1.Type().Default()) - replaceResultArg(a1, arg2) + replaceResultArg(arg1, arg2) } } }) |
