diff options
| author | Dmitry Vyukov <dvyukov@google.com> | 2018-08-01 19:24:21 +0200 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2018-08-02 16:57:31 +0200 |
| commit | c8643744fe4be55e516f7ba494777016abc1055e (patch) | |
| tree | c2fe83e2b312132562189b59997b4fbdb1699772 /prog/prog.go | |
| parent | e002278dfb76b3d01fc860997f08ad71c022d1c7 (diff) | |
prog: refactor defaultArg/isDefaultArg
Refactor from single-big-switch to type methods.
Update #538
Diffstat (limited to 'prog/prog.go')
| -rw-r--r-- | prog/prog.go | 145 |
1 files changed, 18 insertions, 127 deletions
diff --git a/prog/prog.go b/prog/prog.go index 53e0fbe33..edfbd762c 100644 --- a/prog/prog.go +++ b/prog/prog.go @@ -60,13 +60,13 @@ func (arg *ConstArg) Value() (uint64, uint64) { return arg.Val, 0 case *LenType: return arg.Val, 0 + case *ResourceType: + return arg.Val, 0 case *CsumType: // Checksums are computed dynamically in executor. return 0, 0 - case *ResourceType: - return arg.Val, 0 case *ProcType: - if arg.Val == typ.Default() { + if arg.Val == procDefaultValue { return 0, 0 } return typ.ValuesStart + arg.Val, typ.ValuesPerProc @@ -276,119 +276,8 @@ func InnerArg(arg Arg) Arg { return arg // Not a pointer. } -func (target *Target) defaultArg(t Type) Arg { - switch typ := t.(type) { - case *IntType, *ConstType, *FlagsType, *LenType, *ProcType, *CsumType: - return MakeConstArg(t, t.Default()) - case *ResourceType: - return MakeResultArg(t, nil, typ.Default()) - case *BufferType: - if t.Dir() == DirOut { - var sz uint64 - if !typ.Varlen() { - sz = typ.Size() - } - return MakeOutDataArg(t, sz) - } - var data []byte - if !typ.Varlen() { - data = make([]byte, typ.Size()) - } - return MakeDataArg(t, data) - case *ArrayType: - var elems []Arg - if typ.Kind == ArrayRangeLen && typ.RangeBegin == typ.RangeEnd { - for i := uint64(0); i < typ.RangeBegin; i++ { - elems = append(elems, target.defaultArg(typ.Type)) - } - } - return MakeGroupArg(t, elems) - case *StructType: - var inner []Arg - for _, field := range typ.Fields { - inner = append(inner, target.defaultArg(field)) - } - return MakeGroupArg(t, inner) - case *UnionType: - return MakeUnionArg(t, target.defaultArg(typ.Fields[0])) - case *VmaType: - if t.Optional() { - return MakeNullPointerArg(t) - } - return MakeVmaPointerArg(t, 0, target.PageSize) - case *PtrType: - if t.Optional() { - return MakeNullPointerArg(t) - } - return MakePointerArg(t, 0, target.defaultArg(typ.Type)) - default: - panic(fmt.Sprintf("unknown arg type: %#v", t)) - } -} - -func (target *Target) isDefaultArg(arg Arg) bool { - if IsPad(arg.Type()) { - return true - } - switch a := arg.(type) { - case *ConstArg: - switch t := a.Type().(type) { - case *IntType, *ConstType, *FlagsType, *LenType, *ProcType, *CsumType: - return a.Val == t.Default() - default: - panic(fmt.Sprintf("unknown const type: %#v", t)) - } - case *GroupArg: - if !a.fixedInnerSize() && len(a.Inner) != 0 { - return false - } - for _, elem := range a.Inner { - if !target.isDefaultArg(elem) { - return false - } - } - return true - case *UnionArg: - t := a.Type().(*UnionType) - return a.Option.Type().FieldName() == t.Fields[0].FieldName() && - target.isDefaultArg(a.Option) - case *DataArg: - if a.Size() == 0 { - return true - } - if a.Type().Varlen() { - return false - } - if a.Type().Dir() == DirOut { - return true - } - for _, v := range a.Data() { - if v != 0 { - return false - } - } - return true - case *PointerArg: - switch t := a.Type().(type) { - case *PtrType: - if t.Optional() { - return a.IsNull() - } - return a.Address == 0 && target.isDefaultArg(a.Res) - case *VmaType: - if t.Optional() { - return a.IsNull() - } - return a.Address == 0 && a.VmaSize == target.PageSize - default: - panic(fmt.Sprintf("unknown pointer type: %#v", t)) - } - case *ResultArg: - t := a.Type().(*ResourceType) - return a.Res == nil && a.OpDiv == 0 && a.OpAdd == 0 && - len(a.uses) == 0 && a.Val == t.Default() - } - return false +func isDefault(arg Arg) bool { + return arg.Type().isDefaultArg(arg) } func (p *Prog) insertBefore(c *Call, calls []*Call) { @@ -456,18 +345,20 @@ func replaceResultArg(arg, arg1 *ResultArg) { // 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 { - 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(arg1, arg2) + a, ok := arg.(*ResultArg) + if !ok { + return + } + if a.Res != nil { + uses := a.Res.uses + if !uses[a] { + panic("broken tree") } + delete(uses, a) + } + for arg1 := range a.uses { + arg2 := arg1.Type().makeDefaultArg().(*ResultArg) + replaceResultArg(arg1, arg2) } }) } |
