diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2021-08-24 15:50:19 +0000 |
|---|---|---|
| committer | Aleksandr Nogikh <wp32pw@gmail.com> | 2021-09-22 15:40:02 +0200 |
| commit | a7ce77be27d8e3728b97122a005bc5b23298cfc3 (patch) | |
| tree | 1f3adbdd7719ec9c6bf7eb4d48f308004410f775 /prog/encodingexec.go | |
| parent | 041a868956e51efc0dace9e3dff874332a8cdccc (diff) | |
all: introduce call properties
Call properties let us specify how each individual call within a program
must be executed. So far the only way to enforce extra rules was to pass
extra program-level properties (e.g. that is how fault injection was done).
However, it entangles the logic and not flexible enough.
Implement an ability to pass properties along with each individual call.
Diffstat (limited to 'prog/encodingexec.go')
| -rw-r--r-- | prog/encodingexec.go | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/prog/encodingexec.go b/prog/encodingexec.go index e0c7ec59d..296fcf0cf 100644 --- a/prog/encodingexec.go +++ b/prog/encodingexec.go @@ -6,7 +6,7 @@ // Exec format is an sequence of uint64's which encodes a sequence of calls. // The sequence is terminated by a speciall call execInstrEOF. -// Each call is (call ID, copyout index, number of arguments, arguments...). +// Each call is (call ID, call props, copyout index, number of arguments, arguments...). // Each argument is (type, size, value). // There are 4 types of arguments: // - execArgConst: value is const value @@ -22,6 +22,7 @@ package prog import ( "errors" "fmt" + "reflect" "sort" ) @@ -89,6 +90,8 @@ func (w *execContext) serializeCall(c *Call) { w.writeChecksums() // Generate the call itself. w.write(uint64(c.Meta.ID)) + // Generate call properties fragment. + w.writeCallProps(c.Props) if c.Ret != nil && len(c.Ret.uses) != 0 { if _, ok := w.args[c.Ret]; ok { panic("argInfo is already created for return value") @@ -103,6 +106,7 @@ func (w *execContext) serializeCall(c *Call) { for _, arg := range c.Args { w.writeArg(arg) } + // Generate copyout instructions that persist interesting return values. w.writeCopyout(c) } @@ -124,6 +128,17 @@ type argInfo struct { Ret bool } +func (w *execContext) writeCallProps(props CallProps) { + props.ForeachProp(func(_, _ string, value reflect.Value) { + switch kind := value.Kind(); kind { + case reflect.Int: + w.write(uint64(value.Int())) + default: + panic("Unsupported (yet) kind: " + kind.String()) + } + }) +} + func (w *execContext) writeCopyin(c *Call) { ForeachArg(c, func(arg Arg, ctx *ArgCtx) { if ctx.Base == nil { |
