diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-12-10 15:49:04 +0100 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-12-10 16:37:02 +0100 |
| commit | 28bd3e371b1f31cb243f0df56b9c7720971a89db (patch) | |
| tree | ac2ff223b4b855f0bcb554bc65dcff07a2f4e49c /prog/size.go | |
| parent | c7ba317e9bfa7672d851df1217c2c3ea045c55f1 (diff) | |
prog: support AUTO args in programs
AUTO arguments can be used for:
- consts
- lens
- pointers
For const's and len's AUTO is replaced with the natural value,
addresses for AUTO pointers are allocated linearly.
This greatly simplifies writing test programs by hand
as most of the time we want these natural values.
Update tests to use AUTO.
Diffstat (limited to 'prog/size.go')
| -rw-r--r-- | prog/size.go | 76 |
1 files changed, 40 insertions, 36 deletions
diff --git a/prog/size.go b/prog/size.go index c16e7f647..8c95d9c6f 100644 --- a/prog/size.go +++ b/prog/size.go @@ -33,7 +33,7 @@ func (target *Target) generateSize(arg Arg, lenType *LenType) uint64 { } } -func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg) { +func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg, autos map[Arg]bool) { // Create a map from field names to args. argsMap := make(map[string]Arg) for _, arg := range args { @@ -44,54 +44,58 @@ func (target *Target) assignSizes(args []Arg, parentsMap map[Arg]Arg) { } // Fill in size arguments. +nextArg: for _, arg := range args { if arg = InnerArg(arg); arg == nil { continue // Pointer to optional len field, no need to fill in value. } - if typ, ok := arg.Type().(*LenType); ok { - a := arg.(*ConstArg) - - buf, ok := argsMap[typ.Buf] - if ok { - a.Val = target.generateSize(InnerArg(buf), typ) + typ, ok := arg.Type().(*LenType) + if !ok { + continue + } + if autos != nil { + if !autos[arg] { continue } + delete(autos, arg) + } + a := arg.(*ConstArg) - if typ.Buf == "parent" { - a.Val = parentsMap[arg].Size() - if typ.BitSize != 0 { - a.Val = a.Val * 8 / typ.BitSize - } - continue + buf, ok := argsMap[typ.Buf] + if ok { + a.Val = target.generateSize(InnerArg(buf), typ) + continue + } + + if typ.Buf == "parent" { + a.Val = parentsMap[arg].Size() + if typ.BitSize != 0 { + a.Val = a.Val * 8 / typ.BitSize } + continue + } - sizeAssigned := false - for parent := parentsMap[arg]; parent != nil; parent = parentsMap[parent] { - parentName := parent.Type().Name() - if pos := strings.IndexByte(parentName, '['); pos != -1 { - // For template parents, strip arguments. - parentName = parentName[:pos] - } - if typ.Buf == parentName { - a.Val = parent.Size() - if typ.BitSize != 0 { - a.Val = a.Val * 8 / typ.BitSize - } - sizeAssigned = true - break - } + for parent := parentsMap[arg]; parent != nil; parent = parentsMap[parent] { + parentName := parent.Type().Name() + if pos := strings.IndexByte(parentName, '['); pos != -1 { + // For template parents, strip arguments. + parentName = parentName[:pos] } - if sizeAssigned { + if typ.Buf != parentName { continue } - - panic(fmt.Sprintf("len field '%v' references non existent field '%v', argsMap: %+v", - typ.FieldName(), typ.Buf, argsMap)) + a.Val = parent.Size() + if typ.BitSize != 0 { + a.Val = a.Val * 8 / typ.BitSize + } + continue nextArg } + panic(fmt.Sprintf("len field '%v' references non existent field '%v', argsMap: %+v", + typ.FieldName(), typ.Buf, argsMap)) } } -func (target *Target) assignSizesArray(args []Arg) { +func (target *Target) assignSizesArray(args []Arg, autos map[Arg]bool) { parentsMap := make(map[Arg]Arg) for _, arg := range args { ForeachSubArg(arg, func(arg Arg, _ *ArgCtx) { @@ -102,18 +106,18 @@ func (target *Target) assignSizesArray(args []Arg) { } }) } - target.assignSizes(args, parentsMap) + target.assignSizes(args, parentsMap, autos) for _, arg := range args { ForeachSubArg(arg, func(arg Arg, _ *ArgCtx) { if _, ok := arg.Type().(*StructType); ok { - target.assignSizes(arg.(*GroupArg).Inner, parentsMap) + target.assignSizes(arg.(*GroupArg).Inner, parentsMap, autos) } }) } } func (target *Target) assignSizesCall(c *Call) { - target.assignSizesArray(c.Args) + target.assignSizesArray(c.Args, nil) } func (r *randGen) mutateSize(arg *ConstArg, parent []Arg) bool { |
