commit ad518b92d8deb5ed83d1af5de632978abb5ab023
parent 2034c393f958cbd853714557293ea20c1491d879
Author: lash <dev@holbrook.no>
Date: Fri, 31 Mar 2023 13:06:59 +0100
Add frame exit
Diffstat:
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"