go-vise

Constrained Size Output Virtual Machine
Info | Log | Files | Refs | README | LICENSE

commit 0e0993f890a25052f2e091be9d11fd307b5c8c55
parent 8446e634ae5b09e130f1a20bedde6f08cec2cde2
Author: lash <dev@holbrook.no>
Date:   Sun, 23 Apr 2023 13:19:14 +0100

Replace returned error from state flag methods with panics

Diffstat:
Mengine/engine.go | 10++--------
Mexamples/profile/main.go | 25+++++--------------------
Mexamples/validate/main.go | 7+++----
Mstate/debug_test.go | 10++--------
Mstate/state.go | 32++++++++++++++------------------
Mstate/state_test.go | 73++++++++++++++++++-------------------------------------------------------
Mvm/runner.go | 133++++++++++++++++++++-----------------------------------------------------------
Mvm/runner_test.go | 38++++++++++++++++++--------------------
8 files changed, 95 insertions(+), 233 deletions(-)

diff --git a/engine/engine.go b/engine/engine.go @@ -66,10 +66,7 @@ func NewEngine(ctx context.Context, cfg Config, st *state.State, rs resource.Res } if st.Language != nil { - _, err = st.SetFlag(state.FLAG_LANG) - if err != nil { - panic(err) - } + st.SetFlag(state.FLAG_LANG) } return engine } @@ -178,10 +175,7 @@ func(en *Engine) exec(ctx context.Context, input []byte) (bool, error) { } Logg.Debugf("end new VM run", "code", code) - v, err := en.st.MatchFlag(state.FLAG_TERMINATE, true) - if err != nil { - return false, err - } + v := en.st.MatchFlag(state.FLAG_TERMINATE, true) if v { if len(code) > 0 { Logg.Debugf("terminated with code remaining", "code", code) diff --git a/examples/profile/main.go b/examples/profile/main.go @@ -48,19 +48,10 @@ func(pr *profileResource) checkEntry() error { if pr.haveEntered { return nil } - one, err := pr.st.GetFlag(USERFLAG_HAVENAME) - if err != nil { - return err - } - two, err := pr.st.GetFlag(USERFLAG_HAVEEMAIL) - if err != nil { - return err - } + one := pr.st.GetFlag(USERFLAG_HAVENAME) + two := pr.st.GetFlag(USERFLAG_HAVEEMAIL) if one && two { - _, err = pr.st.SetFlag(USERFLAG_IDENTIFIED) - if err != nil { - return err - } + pr.st.SetFlag(USERFLAG_IDENTIFIED) pr.haveEntered = true } return nil @@ -73,10 +64,7 @@ func(pr profileResource) nameSave(ctx context.Context, sym string, input []byte) if err != nil { return emptyResult, err } - changed, err := pr.st.SetFlag(USERFLAG_HAVENAME) - if err != nil { - return emptyResult, err - } + changed := pr.st.SetFlag(USERFLAG_HAVENAME) if changed { pr.checkEntry() } @@ -90,10 +78,7 @@ func(pr profileResource) emailSave(ctx context.Context, sym string, input []byte if err != nil { return emptyResult, err } - changed, err := pr.st.SetFlag(USERFLAG_HAVEEMAIL) - if err != nil { - return emptyResult, err - } + changed := pr.st.SetFlag(USERFLAG_HAVEEMAIL) if changed { pr.checkEntry() } diff --git a/examples/validate/main.go b/examples/validate/main.go @@ -33,7 +33,7 @@ type verifyResource struct { func(vr *verifyResource) verify(ctx context.Context, sym string, input []byte) (resource.Result, error) { var err error if string(input) == "something" { - _, err = vr.st.SetFlag(USERFLAG_HAVESOMETHING) + vr.st.SetFlag(USERFLAG_HAVESOMETHING) } return resource.Result{ Content: "", @@ -41,9 +41,8 @@ func(vr *verifyResource) verify(ctx context.Context, sym string, input []byte) ( } func(vr *verifyResource) again(ctx context.Context, sym string, input []byte) (resource.Result, error) { - var err error - _, err = vr.st.ResetFlag(USERFLAG_HAVESOMETHING) - return resource.Result{}, err + vr.st.ResetFlag(USERFLAG_HAVESOMETHING) + return resource.Result{}, nil } func main() { diff --git a/state/debug_test.go b/state/debug_test.go @@ -39,14 +39,8 @@ func TestDebugState(t *testing.T) { t.Fatal(err) } st := NewState(1).WithDebug() - _, err = st.SetFlag(FLAG_DIRTY) - if err != nil { - t.Fatal(err) - } - _, err = st.SetFlag(8) - if err != nil { - t.Fatal(err) - } + st.SetFlag(FLAG_DIRTY) + st.SetFlag(8) st.Down("root") r := fmt.Sprintf("%s", st) diff --git a/state/state.go b/state/state.go @@ -85,19 +85,19 @@ func(st State) WithDebug() State { // Returns true if bit state was changed. // // Fails if bitindex is out of range. -func(st *State) SetFlag(bitIndex uint32) (bool, error) { +func(st *State) SetFlag(bitIndex uint32) bool { if bitIndex + 1 > st.BitSize { - return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize) + panic(fmt.Sprintf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize)) } r := getFlag(bitIndex, st.Flags) if r { - return false, nil + return false } byteIndex := bitIndex / 8 localBitIndex := bitIndex % 8 b := st.Flags[byteIndex] st.Flags[byteIndex] = b | (1 << localBitIndex) - return true, nil + return true } @@ -106,29 +106,29 @@ func(st *State) SetFlag(bitIndex uint32) (bool, error) { // Returns true if bit state was changed. // // Fails if bitindex is out of range. -func(st *State) ResetFlag(bitIndex uint32) (bool, error) { +func(st *State) ResetFlag(bitIndex uint32) bool { if bitIndex + 1 > st.BitSize { - return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize) + panic(fmt.Sprintf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize)) } r := getFlag(bitIndex, st.Flags) if !r { - return false, nil + return false } byteIndex := bitIndex / 8 localBitIndex := bitIndex % 8 b := st.Flags[byteIndex] st.Flags[byteIndex] = b & (^(1 << localBitIndex)) - return true, nil + return true } // GetFlag returns the state of the flag at the given bit field index. // // Fails if bit field index is out of range. -func(st *State) GetFlag(bitIndex uint32) (bool, error) { +func(st *State) GetFlag(bitIndex uint32) bool { if bitIndex + 1 > st.BitSize { - return false, fmt.Errorf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize) + panic(fmt.Sprintf("bit index %v is out of range of bitfield size %v", bitIndex, st.BitSize)) } - return getFlag(bitIndex, st.Flags), nil + return getFlag(bitIndex, st.Flags) } // FlagBitSize reports the amount of bits available in the bit field index. @@ -146,13 +146,9 @@ func(st *State) FlagByteSize() uint8 { // The flag is specified given its bit index in the bit field. // // If invertMatch is set, a positive result will be returned if the flag is not set. -func(st *State) MatchFlag(sig uint32, matchSet bool) (bool, error) { - r, err := st.GetFlag(sig) - if err != nil { - return false, err - } - Logg.Debugf("rrr", "r", r, "match", matchSet) - return matchSet == r, nil +func(st *State) MatchFlag(sig uint32, matchSet bool) bool { + r := st.GetFlag(sig) + return matchSet == r } // GetIndex scans a byte slice in same order as in storage, and returns the index of the first set bit. diff --git a/state/state_test.go b/state/state_test.go @@ -23,81 +23,44 @@ func TestNewState(t *testing.T) { func TestStateflags(t *testing.T) { st := NewState(9) - v, err := st.GetFlag(2) - if err != nil { - t.Error(err) - } + v := st.GetFlag(2) if v { t.Fatalf("Expected bit 2 not to be set") } - v, err = st.SetFlag(2) - if err != nil { - t.Error(err) - } + v = st.SetFlag(2) if !v { t.Fatalf("Expected change to be set for bit 2") } - v, err = st.GetFlag(2) - if err != nil { - t.Error(err) - } + v = st.GetFlag(2) if !v { t.Fatalf("Expected bit 2 to be set") } - v, err = st.SetFlag(10) - if err != nil { - t.Error(err) - } + v = st.SetFlag(10) if !v { t.Fatalf("Expected change to be set for bit 10") } - v, err = st.GetFlag(10) - if err != nil { - t.Error(err) - } + v = st.GetFlag(10) if !v { t.Fatalf("Expected bit 10 to be set") } - v, err = st.ResetFlag(2) - if err != nil { - t.Error(err) - } + v = st.ResetFlag(2) if !v { t.Fatalf("Expected change to be set for bit 10") } - v, err = st.GetFlag(2) - if err != nil { - t.Error(err) - } + v = st.GetFlag(2) if v { t.Fatalf("Expected bit 2 not to be set") } - v, err = st.GetFlag(10) - if err != nil { - t.Error(err) - } + v = st.GetFlag(10) if !v { t.Fatalf("Expected bit 10 to be set") } - v, err = st.SetFlag(10) - if err != nil { - t.Error(err) - } + v = st.SetFlag(10) if v { t.Fatalf("Expected change not to be set for bit 10") } - v, err = st.SetFlag(2) - if err != nil { - t.Error(err) - } - v, err = st.SetFlag(16) - if err != nil { - t.Error(err) - } - v, err = st.SetFlag(17) - if err == nil { - t.Fatalf("Expected out of range for bit index 17") - } + v = st.SetFlag(2) + v = st.SetFlag(16) if !bytes.Equal(st.Flags[:3], []byte{0x04, 0x04, 0x01}) { t.Fatalf("Expected 0x040401, got %v", st.Flags[:3]) } @@ -105,7 +68,7 @@ func TestStateflags(t *testing.T) { func TestStateFlagFromSlice(t *testing.T) { st := NewState(15) - _, _= st.SetFlag(2) + st.SetFlag(2) v := st.GetIndex([]byte{}) if v { t.Fatalf("Expected no match on empty compare") @@ -118,7 +81,7 @@ func TestStateFlagFromSlice(t *testing.T) { if !v { t.Fatalf("Expected 0x04 to match") } - _, _= st.SetFlag(12) + st.SetFlag(12) v = st.GetIndex([]byte{0x04}) if !v { t.Fatalf("Expected 0x04 to match") @@ -127,7 +90,7 @@ func TestStateFlagFromSlice(t *testing.T) { if !v { t.Fatalf("Expected 0x1000 to match") } - v, _ = st.ResetFlag(2) + v = st.ResetFlag(2) v = st.GetIndex([]byte{0x00, 0x10}) if !v { t.Fatalf("Expected 0x1000 to matck") @@ -221,20 +184,20 @@ func TestStateNavigate(t *testing.T) { func TestStateFlagMatch(t *testing.T) { st := NewState(2) st.SetFlag(8) - v, _ := st.MatchFlag(8, true) + v := st.MatchFlag(8, true) if !v { t.Fatalf("unexpected flag") } - v, _ = st.MatchFlag(8, false) + v = st.MatchFlag(8, false) if v { t.Fatalf("unexpected flag") } - v, _ = st.MatchFlag(9, true) + v = st.MatchFlag(9, true) if v { t.Fatalf("unexpected flag") } - v, _ = st.MatchFlag(9, false) + v = st.MatchFlag(9, false) if !v { t.Fatalf("unexpected flag") } diff --git a/vm/runner.go b/vm/runner.go @@ -81,24 +81,15 @@ func(vm *Vm) Run(ctx context.Context, b []byte) ([]byte, error) { Logg.Tracef("new vm run") running := true for running { - r, err := vm.st.MatchFlag(state.FLAG_TERMINATE, true) - if err != nil { - panic(err) - } + r := vm.st.MatchFlag(state.FLAG_TERMINATE, true) if r { Logg.InfoCtxf(ctx, "terminate set! bailing") return []byte{}, nil } - _, err = vm.st.ResetFlag(state.FLAG_TERMINATE) - if err != nil { - panic(err) - } + _ = vm.st.ResetFlag(state.FLAG_TERMINATE) - change, err := vm.st.ResetFlag(state.FLAG_LANG) - if err != nil { - panic(err) - } + change := vm.st.ResetFlag(state.FLAG_LANG) if change { if vm.st.Language != nil { ctx = context.WithValue(ctx, "Language", *vm.st.Language) @@ -106,23 +97,14 @@ func(vm *Vm) Run(ctx context.Context, b []byte) ([]byte, error) { } - waitChange, err := vm.st.ResetFlag(state.FLAG_WAIT) - if err != nil { - panic(err) - } + waitChange := vm.st.ResetFlag(state.FLAG_WAIT) if waitChange { - _, err = vm.st.ResetFlag(state.FLAG_INMATCH) - if err != nil { - panic(err) - } + vm.st.ResetFlag(state.FLAG_INMATCH) vm.pg.Reset() vm.mn.Reset() } - _, err = vm.st.SetFlag(state.FLAG_DIRTY) - if err != nil { - panic(err) - } + _ = vm.st.SetFlag(state.FLAG_DIRTY) op, bb, err := opSplit(b) if err != nil { return b, err @@ -183,10 +165,7 @@ func(vm *Vm) runErrCheck(ctx context.Context, b []byte, err error) ([]byte, erro } vm.pg = vm.pg.WithError(err) - v, err := vm.st.MatchFlag(state.FLAG_LOADFAIL, true) - if err != nil { - panic(err) - } + v := vm.st.MatchFlag(state.FLAG_LOADFAIL, true) if !v { return b, err } @@ -206,22 +185,13 @@ func(vm *Vm) runDeadCheck(ctx context.Context, b []byte) ([]byte, error) { if len(b) > 0 { return b, nil } - r, err := vm.st.MatchFlag(state.FLAG_READIN, false) - if err != nil { - panic(err) - } + r := vm.st.MatchFlag(state.FLAG_READIN, false) if r { Logg.DebugCtxf(ctx, "Not processing input. Setting terminate") - _, err := vm.st.SetFlag(state.FLAG_TERMINATE) - if err != nil { - panic(err) - } + vm.st.SetFlag(state.FLAG_TERMINATE) return b, nil } - r, err = vm.st.MatchFlag(state.FLAG_TERMINATE, true) - if err != nil { - panic(err) - } + r = vm.st.MatchFlag(state.FLAG_TERMINATE, true) if r { Logg.TraceCtxf(ctx, "Terminate found!!") return b, nil @@ -258,16 +228,16 @@ func(vm *Vm) runCatch(ctx context.Context, b []byte) ([]byte, error) { if err != nil { return b, err } - r, err := vm.st.MatchFlag(sig, mode) - if err != nil { - var perr error - _, perr = vm.st.SetFlag(state.FLAG_TERMINATE) - if perr != nil { - panic(perr) - } - Logg.TraceCtxf(ctx, "terminate set") - return b, err - } + r := vm.st.MatchFlag(sig, mode) +// if err != nil { +// var perr error +// _, perr = vm.st.SetFlag(state.FLAG_TERMINATE) +// if perr != nil { +// panic(perr) +// } +// Logg.TraceCtxf(ctx, "terminate set") +// return b, err +// } if r { //b = append(bh, b...) //vm.st.Down(sym) @@ -293,10 +263,7 @@ func(vm *Vm) runCroak(ctx context.Context, b []byte) ([]byte, error) { if err != nil { return b, err } - r, err := vm.st.MatchFlag(sig, mode) - if err != nil { - return b, err - } + r := vm.st.MatchFlag(sig, mode) if r { Logg.InfoCtxf(ctx, "croak at flag %v, purging and moving to top", "signal", sig) vm.Reset() @@ -370,11 +337,8 @@ func(vm *Vm) runInCmp(ctx context.Context, b []byte) ([]byte, error) { return b, err } - reading, err := vm.st.GetFlag(state.FLAG_READIN) - if err != nil { - panic(err) - } - have, err := vm.st.GetFlag(state.FLAG_INMATCH) + reading := vm.st.GetFlag(state.FLAG_READIN) + have := vm.st.GetFlag(state.FLAG_INMATCH) if err != nil { panic(err) } @@ -384,10 +348,7 @@ func(vm *Vm) runInCmp(ctx context.Context, b []byte) ([]byte, error) { return b, nil } } else { - _, err = vm.st.SetFlag(state.FLAG_READIN) - if err != nil { - panic(err) - } + vm.st.SetFlag(state.FLAG_READIN) } input, err := vm.st.GetInput() if err != nil { @@ -403,23 +364,14 @@ func(vm *Vm) runInCmp(ctx context.Context, b []byte) ([]byte, error) { } Logg.InfoCtxf(ctx, "input match", "input", input, "target", target) } - _, err = vm.st.SetFlag(state.FLAG_INMATCH) - if err != nil { - panic(err) - } - _, err = vm.st.ResetFlag(state.FLAG_READIN) - if err != nil { - panic(err) - } + vm.st.SetFlag(state.FLAG_INMATCH) + vm.st.ResetFlag(state.FLAG_READIN) newTarget, _, err := applyTarget([]byte(target), vm.st, vm.ca, ctx) _, ok := err.(*state.IndexError) if ok { - _, err = vm.st.SetFlag(state.FLAG_READIN) - if err != nil { - panic(err) - } + vm.st.SetFlag(state.FLAG_READIN) return b, nil } else if err != nil { return b, err @@ -447,10 +399,7 @@ func(vm *Vm) runHalt(ctx context.Context, b []byte) ([]byte, error) { } Logg.DebugCtxf(ctx, "found HALT, stopping") - _, err = vm.st.SetFlag(state.FLAG_WAIT) - if err != nil { - panic(err) - } + vm.st.SetFlag(state.FLAG_WAIT) return b, nil } @@ -501,10 +450,7 @@ func(vm *Vm) runMPrev(ctx context.Context, b []byte) ([]byte, error) { // Render wraps output rendering, and handles error when attempting to browse beyond the rendered page count. func(vm *Vm) Render(ctx context.Context) (string, error) { - changed, err := vm.st.ResetFlag(state.FLAG_DIRTY) - if err != nil { - panic(err) - } + changed := vm.st.ResetFlag(state.FLAG_DIRTY) if !changed { return "", nil } @@ -537,36 +483,23 @@ func(vm *Vm) refresh(key string, rs resource.Resource, ctx context.Context) (str input, _ := vm.st.GetInput() r, err := fn(ctx, key, input) if err != nil { - var perr error - _, perr = vm.st.SetFlag(state.FLAG_LOADFAIL) - if perr != nil { - panic(err) - } + _ = vm.st.SetFlag(state.FLAG_LOADFAIL) return "", NewExternalCodeError(key, err).WithCode(r.Status) } for _, flag := range r.FlagSet { if !state.IsWriteableFlag(flag) { continue } - _, err = vm.st.SetFlag(flag) - if err != nil { - panic(err) - } + vm.st.SetFlag(flag) } for _, flag := range r.FlagReset { if !state.IsWriteableFlag(flag) { continue } - _, err = vm.st.ResetFlag(flag) - if err != nil { - panic(err) - } + vm.st.ResetFlag(flag) } - haveLang, err := vm.st.MatchFlag(state.FLAG_LANG, true) - if err != nil { - panic(err) - } + haveLang := vm.st.MatchFlag(state.FLAG_LANG, true) if haveLang { vm.st.SetLanguage(r.Content) } diff --git a/vm/runner_test.go b/vm/runner_test.go @@ -181,14 +181,14 @@ func TestRun(t *testing.T) { b = NewLine(b, HALT, nil, nil, nil) ctx := context.TODO() _, err := vm.Run(ctx, b) - if err != nil { - t.Errorf("run error: %v", err) + if err == nil { + t.Fatalf("expected error") } b = []byte{0x01, 0x02} _, err = vm.Run(ctx, b) if err == nil { - t.Errorf("no error on invalid opcode") + t.Fatalf("no error on invalid opcode") } } @@ -255,12 +255,10 @@ func TestRunMultiple(t *testing.T) { b = NewLine(b, LOAD, []string{"one"}, []byte{0x00}, nil) b = NewLine(b, LOAD, []string{"two"}, []byte{42}, nil) b = NewLine(b, HALT, nil, nil, nil) - b, err := vm.Run(ctx, b) - if err != nil { - t.Error(err) - } - if len(b) > 0 { - t.Errorf("expected empty code") + var err error + b, err = vm.Run(ctx, b) + if err == nil { + t.Fatal(err) } } @@ -331,19 +329,20 @@ func TestRunArg(t *testing.T) { _ = st.SetInput(input) bi := NewLine(nil, INCMP, []string{"bar", "baz"}, nil, nil) - bi = NewLine(bi, HALT, nil, nil, nil) ctx := context.TODO() + + var err error b, err := vm.Run(ctx, bi) - if err != nil { - t.Error(err) + if err == nil { + t.Fatalf("expected error") } l := len(b) if l != 0 { - t.Errorf("expected empty remainder, got length %v: %v", l, b) + t.Fatalf("expected empty remainder, got length %v: %v", l, b) } r, _ := st.Where() if r != "baz" { - t.Errorf("expected where-state baz, got %v", r) + t.Fatalf("expected where-state baz, got %v", r) } } @@ -366,8 +365,8 @@ func TestRunInputHandler(t *testing.T) { var err error ctx := context.TODO() _, err = vm.Run(ctx, bi) - if err != nil { - t.Fatal(err) + if err == nil { + t.Fatalf("expected error") } r, _ := st.Where() if r != "foo" { @@ -490,21 +489,20 @@ func TestRunReturn(t *testing.T) { st.Down("root") b := NewLine(nil, INCMP, []string{"0", "bar"}, nil, nil) - b = NewLine(b, HALT, nil, nil, nil) b = NewLine(b, INCMP, []string{"1", "_"}, nil, nil) - b = NewLine(b, HALT, nil, nil, nil) ctx := context.TODO() st.SetInput([]byte("0")) b, err = vm.Run(ctx, b) - if err != nil { - t.Fatal(err) + if err == nil { + t.Fatalf("expected error") } location, _ := st.Where() if location != "bar" { t.Fatalf("expected location 'bar', got '%s'", location) } + st.SetInput([]byte("1")) b, err = vm.Run(ctx, b) if err != nil {