Full test (which fails)

This commit is contained in:
Ian Gulliver
2021-11-18 17:53:38 -10:00
parent 8e34c67f11
commit e99387beb4
5 changed files with 27 additions and 22 deletions

View File

@@ -27,4 +27,8 @@ functions:
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if state.GlobalMemory().MustReadUnsigned(0) != 3 {
t.Fatalf("Expected 3, found %d\n", state.GlobalMemory().MustReadUnsigned(0))
}
} }

View File

@@ -41,12 +41,5 @@ func NewInstructionsFromByteCode(byteCode []byte) ([]*Instruction, error) {
instrs = append(instrs, instr) instrs = append(instrs, instr)
} }
if len(instrs) == 0 || instrs[len(instrs)-1].OpCode != OpReturn {
// Add implicit return at the end of each function
instrs = append(instrs, &Instruction{
OpCode: OpReturn,
})
}
return instrs, nil return instrs, nil
} }

View File

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

View File

@@ -3,13 +3,13 @@ package vm
type stackFrame struct { type stackFrame struct {
previousFunctionIndex int64 previousFunctionIndex int64
previousInstructionIndex int64 previousInstructionIndex int64
functionMemory *memory functionMemory *Memory
} }
func newStackFrame(state *State) *stackFrame { func newStackFrame(state *State) *stackFrame {
return &stackFrame{ return &stackFrame{
previousFunctionIndex: state.functionIndex, previousFunctionIndex: state.functionIndex,
previousInstructionIndex: state.instructionIndex, previousInstructionIndex: state.instructionIndex,
functionMemory: newMemory(16), functionMemory: NewMemory(16),
} }
} }

View File

@@ -13,14 +13,14 @@ type State struct {
instructionIndex int64 instructionIndex int64
comparisonResult bool comparisonResult bool
globalMemory *memory 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(16), globalMemory: NewMemory(16),
}, nil }, nil
} }
@@ -51,6 +51,10 @@ func (state *State) Execute() error {
return state.err return state.err
} }
func (state *State) GlobalMemory() *Memory {
return state.globalMemory
}
func (state *State) stackFrame() *stackFrame { func (state *State) stackFrame() *stackFrame {
return state.stack[len(state.stack)-1] return state.stack[len(state.stack)-1]
} }
@@ -83,6 +87,10 @@ func (state *State) processInstruction() {
instr := fnc[state.instructionIndex] instr := fnc[state.instructionIndex]
state.instructionIndex += 1 state.instructionIndex += 1
instr.opHandler(state, instr) instr.opHandler(state, instr)
if state.instructionIndex >= int64(len(fnc)) {
state.ret()
}
} }
func (state *State) readUnsigned(op *Operand) uint64 { func (state *State) readUnsigned(op *Operand) uint64 {
@@ -91,14 +99,14 @@ func (state *State) readUnsigned(op *Operand) uint64 {
return op.Value return op.Value
case FunctionMemoryIndex: case FunctionMemoryIndex:
value, err := state.stackFrame().functionMemory.readUnsigned(op.Value) value, err := state.stackFrame().functionMemory.ReadUnsigned(op.Value)
if err != nil { if err != nil {
state.setError(err) state.setError(err)
} }
return value return value
case GlobalMemoryIndex: case GlobalMemoryIndex:
value, err := state.globalMemory.readUnsigned(op.Value) value, err := state.globalMemory.ReadUnsigned(op.Value)
if err != nil { if err != nil {
state.setError(err) state.setError(err)
} }
@@ -120,13 +128,13 @@ func (state *State) writeUnsigned(op *Operand, value uint64) {
state.setError(fmt.Errorf("Write to literal operand")) state.setError(fmt.Errorf("Write to literal operand"))
case FunctionMemoryIndex: case FunctionMemoryIndex:
err := state.stackFrame().functionMemory.writeUnsigned(op.Value, value) err := state.stackFrame().functionMemory.WriteUnsigned(op.Value, value)
if err != nil { if err != nil {
state.setError(err) state.setError(err)
} }
case GlobalMemoryIndex: case GlobalMemoryIndex:
err := state.globalMemory.writeUnsigned(op.Value, value) err := state.globalMemory.WriteUnsigned(op.Value, value)
if err != nil { if err != nil {
state.setError(err) state.setError(err)
} }