prog: remove ReturnArg

It's not all that needed.
This commit is contained in:
Dmitry Vyukov 2018-05-05 09:08:48 +02:00
parent b438ff2328
commit 5ca897bd50
4 changed files with 23 additions and 40 deletions

View File

@ -63,10 +63,6 @@ func clone(arg Arg, newargs map[Arg]Arg) Arg {
a1 := new(ResultArg)
*a1 = *a
arg1 = a1
case *ReturnArg:
a1 := new(ReturnArg)
*a1 = *a
arg1 = a1
default:
panic("bad arg kind")
}

View File

@ -153,7 +153,10 @@ func (p *Prog) SerializeForExec(buffer []byte) (int, error) {
// Generate the call itself.
w.write(uint64(c.Meta.ID))
if isUsed(c.Ret) {
w.args[c.Ret] = argInfo{Idx: copyoutSeq}
if _, ok := w.args[c.Ret]; ok {
panic("argInfo is already created for return value")
}
w.args[c.Ret] = argInfo{Idx: copyoutSeq, Ret: true}
w.write(copyoutSeq)
copyoutSeq++
} else {
@ -169,11 +172,12 @@ func (p *Prog) SerializeForExec(buffer []byte) (int, error) {
return
}
switch arg.(type) {
case *ReturnArg:
// Idx is already assigned above.
case *ConstArg, *ResultArg:
// Create a separate copyout instruction that has own Idx.
info := w.args[arg]
if info.Ret {
break // Idx is already assigned above.
}
info.Idx = copyoutSeq
copyoutSeq++
w.args[arg] = info
@ -210,6 +214,7 @@ type execContext struct {
type argInfo struct {
Addr uint64 // physical addr
Idx uint64 // copyout instruction index
Ret bool
}
func (w *execContext) write(v uint64) {

View File

@ -255,7 +255,8 @@ func (arg *UnionArg) Size() uint64 {
}
// Used for ResourceType.
// Either holds constant value or reference another ResultArg or ReturnArg.
// This is the only argument that can be used as syscall return value.
// Either holds constant value or reference another ResultArg.
type ResultArg struct {
ArgCommon
Res Arg // reference to arg which we use
@ -278,6 +279,14 @@ func MakeResultArg(t Type, r Arg, v uint64) *ResultArg {
return arg
}
func MakeReturnArg(t Type) *ResultArg {
// TODO(dvyukov): we should not create return arg at all if t is nil.
if t != nil && t.Dir() != DirOut {
panic("return arg is not out")
}
return &ResultArg{ArgCommon: ArgCommon{typ: t}}
}
func (arg *ResultArg) Size() uint64 {
return arg.typ.Size()
}
@ -290,25 +299,6 @@ func (arg *ResultArg) Uses() *Arg {
return &arg.Res
}
// Used for ResourceType and VmaType.
// This argument denotes syscall return value.
type ReturnArg struct {
ArgCommon
uses map[Arg]bool // ArgResult args that use this arg
}
func MakeReturnArg(t Type) *ReturnArg {
return &ReturnArg{ArgCommon: ArgCommon{typ: t}}
}
func (arg *ReturnArg) Size() uint64 {
panic("not called")
}
func (arg *ReturnArg) Used() *map[Arg]bool {
return &arg.uses
}
// Returns inner arg for pointer args.
func InnerArg(arg Arg) Arg {
if t, ok := arg.Type().(*PtrType); ok {

View File

@ -43,10 +43,6 @@ func (p *Prog) validateCall(ctx *validCtx, c *Call) error {
c.Meta.Name, len(c.Meta.Args), len(c.Args))
}
for _, arg := range c.Args {
if _, ok := arg.(*ReturnArg); ok {
return fmt.Errorf("syscall %v: arg '%v' has wrong return kind",
c.Meta.Name, arg.Type().Name())
}
if err := validateArg(ctx, c, arg); err != nil {
return err
}
@ -54,8 +50,12 @@ func (p *Prog) validateCall(ctx *validCtx, c *Call) error {
if c.Ret == nil {
return fmt.Errorf("syscall %v: return value is absent", c.Meta.Name)
}
if _, ok := c.Ret.(*ReturnArg); !ok {
if ret, ok := c.Ret.(*ResultArg); !ok {
return fmt.Errorf("syscall %v: return value has wrong kind %v", c.Meta.Name, c.Ret)
} else if ret.Type() != nil && ret.Type().Dir() != DirOut {
return fmt.Errorf("syscall %v: return value %v is not output", c.Meta.Name, c.Ret)
} else if ret.Res != nil || ret.Val != 0 || ret.OpDiv != 0 || ret.OpAdd != 0 {
return fmt.Errorf("syscall %v: return value %v is not empty", c.Meta.Name, c.Ret)
}
if c.Meta.Ret != nil {
if err := validateArg(ctx, c, c.Ret); err != nil {
@ -129,7 +129,6 @@ func validateArg(ctx *validCtx, c *Call, arg Arg) error {
return fmt.Errorf("syscall %v: out resource arg '%v' has bad const value %v",
c.Meta.Name, a.Type().Name(), a.Val)
}
case *ReturnArg:
default:
return fmt.Errorf("syscall %v: fd arg '%v' has bad kind %v",
c.Meta.Name, arg.Type().Name(), arg)
@ -310,13 +309,6 @@ func validateArg(ctx *validCtx, c *Call, arg Arg) error {
return fmt.Errorf("syscall %v: result arg '%v' has broken link (%+v)",
c.Meta.Name, a.Type().Name(), *a.Res.(ArgUsed).Used())
}
case *ReturnArg:
switch a.Type().(type) {
case *ResourceType:
default:
return fmt.Errorf("syscall %v: result arg '%v' has bad meta type %+v",
c.Meta.Name, arg.Type().Name(), arg.Type())
}
default:
return fmt.Errorf("syscall %v: unknown arg '%v' kind",
c.Meta.Name, arg.Type().Name())