2017-07-11 14:49:08 +00:00
|
|
|
// Copyright 2017 syzkaller project authors. All rights reserved.
|
2015-10-12 08:16:57 +00:00
|
|
|
// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
package prog
|
|
|
|
|
|
|
|
func (p *Prog) Clone() *Prog {
|
2017-09-14 17:25:01 +00:00
|
|
|
p1 := &Prog{
|
|
|
|
Target: p.Target,
|
2017-12-08 11:27:39 +00:00
|
|
|
Calls: make([]*Call, len(p.Calls)),
|
2017-09-14 17:25:01 +00:00
|
|
|
}
|
2018-05-05 08:13:04 +00:00
|
|
|
newargs := make(map[*ResultArg]*ResultArg)
|
2017-12-08 11:27:39 +00:00
|
|
|
for ci, c := range p.Calls {
|
2015-10-12 08:16:57 +00:00
|
|
|
c1 := new(Call)
|
|
|
|
c1.Meta = c.Meta
|
2018-05-05 08:25:45 +00:00
|
|
|
if c.Ret != nil {
|
|
|
|
c1.Ret = clone(c.Ret, newargs).(*ResultArg)
|
|
|
|
}
|
2017-12-08 11:27:39 +00:00
|
|
|
c1.Args = make([]Arg, len(c.Args))
|
|
|
|
for ai, arg := range c.Args {
|
|
|
|
c1.Args[ai] = clone(arg, newargs)
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
2017-12-08 11:27:39 +00:00
|
|
|
p1.Calls[ci] = c1
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
2018-08-01 17:45:15 +00:00
|
|
|
p1.debugValidate()
|
2017-12-08 11:27:39 +00:00
|
|
|
return p1
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
|
|
|
|
2018-05-05 08:13:04 +00:00
|
|
|
func clone(arg Arg, newargs map[*ResultArg]*ResultArg) Arg {
|
2017-07-11 14:49:08 +00:00
|
|
|
var arg1 Arg
|
|
|
|
switch a := arg.(type) {
|
|
|
|
case *ConstArg:
|
|
|
|
a1 := new(ConstArg)
|
|
|
|
*a1 = *a
|
|
|
|
arg1 = a1
|
|
|
|
case *PointerArg:
|
|
|
|
a1 := new(PointerArg)
|
|
|
|
*a1 = *a
|
|
|
|
arg1 = a1
|
|
|
|
if a.Res != nil {
|
2017-12-08 11:27:39 +00:00
|
|
|
a1.Res = clone(a.Res, newargs)
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
2017-07-11 14:49:08 +00:00
|
|
|
case *DataArg:
|
|
|
|
a1 := new(DataArg)
|
|
|
|
*a1 = *a
|
2017-12-13 19:12:13 +00:00
|
|
|
a1.data = append([]byte{}, a.data...)
|
2017-07-11 14:49:08 +00:00
|
|
|
arg1 = a1
|
|
|
|
case *GroupArg:
|
|
|
|
a1 := new(GroupArg)
|
|
|
|
*a1 = *a
|
|
|
|
arg1 = a1
|
2017-12-08 11:27:39 +00:00
|
|
|
a1.Inner = make([]Arg, len(a.Inner))
|
|
|
|
for i, arg2 := range a.Inner {
|
|
|
|
a1.Inner[i] = clone(arg2, newargs)
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
2017-07-11 14:49:08 +00:00
|
|
|
case *UnionArg:
|
|
|
|
a1 := new(UnionArg)
|
|
|
|
*a1 = *a
|
|
|
|
arg1 = a1
|
2017-12-08 11:27:39 +00:00
|
|
|
a1.Option = clone(a.Option, newargs)
|
2017-07-11 14:49:08 +00:00
|
|
|
case *ResultArg:
|
|
|
|
a1 := new(ResultArg)
|
|
|
|
*a1 = *a
|
|
|
|
arg1 = a1
|
2018-05-05 08:13:04 +00:00
|
|
|
if a1.Res != nil {
|
|
|
|
r := newargs[a1.Res]
|
|
|
|
a1.Res = r
|
|
|
|
if r.uses == nil {
|
|
|
|
r.uses = make(map[*ResultArg]bool)
|
|
|
|
}
|
|
|
|
r.uses[a1] = true
|
|
|
|
}
|
|
|
|
a1.uses = nil // filled when we clone the referent
|
|
|
|
newargs[a] = a1
|
2017-07-11 14:49:08 +00:00
|
|
|
default:
|
|
|
|
panic("bad arg kind")
|
2015-10-12 08:16:57 +00:00
|
|
|
}
|
|
|
|
return arg1
|
|
|
|
}
|