Make memory an object

This commit is contained in:
Ian Gulliver
2021-11-16 16:15:46 -10:00
parent 1fdeaaf4cc
commit 012d5faecf
3 changed files with 51 additions and 12 deletions

39
memory.go Normal file
View File

@@ -0,0 +1,39 @@
package vm
import "fmt"
type memory struct {
entries []uint64
}
func newMemory(size uint64) *memory {
return &memory{
entries: make([]uint64, size),
}
}
func (mem *memory) readUnsigned(index uint64) (uint64, error) {
if index >= uint64(len(mem.entries)) {
return 0, fmt.Errorf("Invalid memory index: %016x", index)
}
return mem.entries[index], nil
}
func (mem *memory) mustReadUnsigned(index uint64) uint64 {
value, err := mem.readUnsigned(index)
if err != nil {
panic(err)
}
return value
}
func (mem *memory) writeUnsigned(index uint64, value uint64) error {
if index >= uint64(len(mem.entries)) {
return fmt.Errorf("Invalid memory index: %016x", index)
}
mem.entries[index] = value
return nil
}

View File

@@ -15,13 +15,14 @@ type State struct {
instructionIndex int64 instructionIndex int64
comparisonResult bool comparisonResult bool
globalMemory [globalMemoryEntries]uint64 globalMemory *memory
stack []*stackFrame stack []*stackFrame
} }
func NewState(functions [][]*Instruction) (*State, error) { func NewState(functions [][]*Instruction) (*State, error) {
return &State{ return &State{
functions: functions, functions: functions,
globalMemory: newMemory(globalMemoryEntries),
}, nil }, nil
} }
@@ -97,11 +98,11 @@ func (state *State) readUnsigned(op *Operand) uint64 {
return state.stackFrame().functionMemory[op.Value] return state.stackFrame().functionMemory[op.Value]
case GlobalMemoryIndex: case GlobalMemoryIndex:
if op.Value >= globalMemoryEntries { value, err := state.globalMemory.readUnsigned(op.Value)
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value)) if err != nil {
return 0 state.setError(err)
} }
return state.globalMemory[op.Value] return value
default: default:
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type)) state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
@@ -126,11 +127,10 @@ func (state *State) writeUnsigned(op *Operand, value uint64) {
state.stackFrame().functionMemory[op.Value] = value state.stackFrame().functionMemory[op.Value] = value
case GlobalMemoryIndex: case GlobalMemoryIndex:
if op.Value >= globalMemoryEntries { err := state.globalMemory.writeUnsigned(op.Value, value)
state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value)) if err != nil {
return state.setError(err)
} }
state.globalMemory[op.Value] = value
default: default:
state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type)) state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))

View File

@@ -41,7 +41,7 @@ func TestFirst(t *testing.T) {
t.Fatal(state) t.Fatal(state)
} }
if state.globalMemory[0] != 3 { if state.globalMemory.mustReadUnsigned(0) != 3 {
t.Fatal(state.globalMemory[0]) t.Fatal(state.globalMemory.mustReadUnsigned(0))
} }
} }