go-vise

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

commit ad518b92d8deb5ed83d1af5de632978abb5ab023
parent 2034c393f958cbd853714557293ea20c1491d879
Author: lash <dev@holbrook.no>
Date:   Fri, 31 Mar 2023 13:06:59 +0100

Add frame exit

Diffstat:
Mgo/state/state.go | 22+++++++++++++++++-----
Mgo/state/state_test.go | 34+++++++++++++++++++++++++++++-----
Mgo/vm/vm_test.go | 4++--
3 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/go/state/state.go b/go/state/state.go @@ -2,18 +2,18 @@ package state import ( "fmt" + "log" ) type State struct { Flags []byte - OutputSize uint16 CacheSize uint32 CacheUseSize uint32 Cache []map[string]string ExecPath []string } -func NewState(bitSize uint64, outputSize uint16) State { +func NewState(bitSize uint64) State { if bitSize == 0 { panic("bitsize cannot be 0") } @@ -24,7 +24,6 @@ func NewState(bitSize uint64, outputSize uint16) State { return State{ Flags: make([]byte, bitSize / 8), - OutputSize: outputSize, CacheSize: 0, CacheUseSize: 0, } @@ -45,7 +44,7 @@ func(st *State) Add(k string, v string) error { if sz == 0 { return fmt.Errorf("Cache capacity exceeded %v of %v", st.CacheUseSize + sz, st.CacheSize) } - fmt.Printf("len %v %v\n", sz, st.CacheUseSize) + log.Printf("add key %s value size %v", k, sz) st.Cache[len(st.Cache)-1][k] = v st.CacheUseSize += sz return nil @@ -55,7 +54,20 @@ func(st *State) Get() (map[string]string, error) { return st.Cache[len(st.Cache)-1], nil } -func (st *State) Exit() { +func (st *State) Exit() error { + l := len(st.Cache) + if l == 0 { + return fmt.Errorf("exit called beyond top frame") + } + l -= 1 + m := st.Cache[l] + for k, v := range m { + sz := len(v) + st.CacheUseSize -= uint32(sz) + log.Printf("free frame %v key %v value size %v", l, k, sz) + } + st.Cache = st.Cache[:l] + return nil } func(st *State) checkCapacity(v string) uint32 { diff --git a/go/state/state_test.go b/go/state/state_test.go @@ -5,15 +5,15 @@ import ( ) func TestNewStateFlags(t *testing.T) { - st := NewState(5, 0) + st := NewState(5) if len(st.Flags) != 1 { t.Errorf("invalid state flag length: %v", len(st.Flags)) } - st = NewState(8, 0) + st = NewState(8) if len(st.Flags) != 1 { t.Errorf("invalid state flag length: %v", len(st.Flags)) } - st = NewState(17, 0) + st = NewState(17) if len(st.Flags) != 3 { t.Errorf("invalid state flag length: %v", len(st.Flags)) @@ -21,7 +21,7 @@ func TestNewStateFlags(t *testing.T) { } func TestNewStateCache(t *testing.T) { - st := NewState(17, 0) + st := NewState(17) if st.CacheSize != 0 { t.Errorf("cache size not 0") } @@ -33,7 +33,7 @@ func TestNewStateCache(t *testing.T) { } func TestStateCacheUse(t *testing.T) { - st := NewState(17, 0) + st := NewState(17) st = st.WithCacheSize(10) st.Enter("foo") err := st.Add("bar", "baz") @@ -49,3 +49,27 @@ func TestStateCacheUse(t *testing.T) { t.Errorf("expected capacity error") } } + +func TestStateEnterExit(t *testing.T) { + st := NewState(17) + st.Enter("one") + err := st.Add("foo", "bar") + if err != nil { + t.Error(err) + } + err = st.Add("baz", "xyzzy") + if err != nil { + t.Error(err) + } + if st.CacheUseSize != 8 { + t.Errorf("expected cache use size 8 got %v", st.CacheUseSize) + } + err = st.Exit() + if err != nil { + t.Error(err) + } + err = st.Exit() + if err == nil { + t.Errorf("expected out of top frame error") + } +} diff --git a/go/vm/vm_test.go b/go/vm/vm_test.go @@ -61,7 +61,7 @@ func (r *TestResource) FuncFor(sym string) (resource.EntryFunc, error) { } func TestRun(t *testing.T) { - st := state.NewState(5, 255) + st := state.NewState(5) rs := TestResource{} b := []byte{0x00, 0x02} r, err := Run(b, st, &rs, context.TODO()) @@ -78,7 +78,7 @@ func TestRun(t *testing.T) { } func TestRunMap(t *testing.T) { - st := state.NewState(5, 255) + st := state.NewState(5) st.Enter("barbarbar") rs := TestResource{} sym := "one"