Make memory an object
This commit is contained in:
39
memory.go
Normal file
39
memory.go
Normal 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
|
||||||
|
}
|
||||||
18
state.go
18
state.go
@@ -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))
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user