Simplify main loop conditional

This commit is contained in:
Ian Gulliver
2021-11-15 20:24:20 -10:00
parent b6d0828e3e
commit 2c063e5382

139
main.go
View File

@@ -9,6 +9,7 @@ import "github.com/lunixbochs/struc"
import "github.com/pkg/errors" import "github.com/pkg/errors"
type OperandType uint8 type OperandType uint8
type OpCodeType uint32
const ( const (
Literal OperandType = 0 Literal OperandType = 0
@@ -16,6 +17,54 @@ const (
GlobalMemoryIndex = 2 GlobalMemoryIndex = 2
) )
const (
OpNoOp OpCodeType = 0x00000000
OpNop = OpNoOp
OpCall = 0x00000001
OpCal = OpCall
OpReturn = 0x00000002
OpRet = OpReturn
OpMove = 0x00000100
OpMov = OpMove
OpAdd = 0x00000200
OpSubtract = 0x00000201
OpSub = OpSubtract
OpMultiply = 0x00000202
OpMul = OpMultiply
OpDivideUnsigned = 0x00000203
OpDivU = OpDivideUnsigned
OpDivideSigned = 0x00000204
OpDivS = OpDivideSigned
OpIsEqual = 0x00000300
OpEq = OpIsEqual
OpIsLessThanUnsigned = 0x00000301
OpLTU = OpIsLessThanUnsigned
OpIsLessThanSigned = 0x00000302
OpLTS = OpIsLessThanSigned
OpIsGreaterThanUnsigned = 0x00000303
OpGTU = OpIsGreaterThanUnsigned
OpIsGreaterThanSigned = 0x00000304
OpGTS = OpIsGreaterThanSigned
OpIsLessThanOrEqualUnsigned = 0x00000305
OpLTEU = OpIsLessThanOrEqualUnsigned
OpIsLessThanOrEqualSigned = 0x00000306
OpLTES = OpIsLessThanOrEqualSigned
OpIsGreaterThanOrEqualUnsigned = 0x00000307
OpGTEU = OpIsGreaterThanOrEqualUnsigned
OpIsGreaterThanOrEqualSigned = 0x00000308
OpGTES = OpIsGreaterThanOrEqualSigned
OpJump = 0x00000400
OpJmp = OpJump
OpJumpIfTrue = 0x00000401
OpJmpT = OpJumpIfTrue
OpJumpIfFalse = 0x00000402
OpJmpF = OpJumpIfFalse
)
const InstructionBytes = 32 const InstructionBytes = 32
const GlobalMemoryEntries = 16 const GlobalMemoryEntries = 16
const FunctionMemoryEntries = 16 const FunctionMemoryEntries = 16
@@ -29,7 +78,7 @@ type Operand struct {
} }
type Instruction struct { type Instruction struct {
OpCode uint32 OpCode OpCodeType
Reserved [4]byte Reserved [4]byte
Operand1 Operand Operand1 Operand
Operand2 Operand Operand2 Operand
@@ -38,6 +87,7 @@ type Instruction struct {
} }
type State struct { type State struct {
Running bool
Error error Error error
Functions [][]*Instruction Functions [][]*Instruction
@@ -55,32 +105,32 @@ type StackFrame struct {
FunctionMemory [FunctionMemoryEntries]uint64 FunctionMemory [FunctionMemoryEntries]uint64
} }
var OpHandlers = map[uint32]OpHandler{ var OpHandlers = map[OpCodeType]OpHandler{
0x00000000: (*State).NoOp, OpNoOp: (*State).NoOp,
0x00000001: (*State).Call, OpCall: (*State).Call,
0x00000002: (*State).Return, OpReturn: (*State).Return,
0x00000100: (*State).Move, OpMove: (*State).Move,
0x00000200: (*State).Add, OpAdd: (*State).Add,
0x00000201: (*State).Subtract, OpSubtract: (*State).Subtract,
0x00000202: (*State).Multiply, OpMultiply: (*State).Multiply,
0x00000203: (*State).DivideUnsigned, OpDivideUnsigned: (*State).DivideUnsigned,
0x00000204: (*State).DivideSigned, OpDivideSigned: (*State).DivideSigned,
0x00000300: (*State).IsEqual, OpIsEqual: (*State).IsEqual,
0x00000301: (*State).IsLessThanUnsigned, OpIsLessThanUnsigned: (*State).IsLessThanUnsigned,
0x00000302: (*State).IsLessThanSigned, OpIsLessThanSigned: (*State).IsLessThanSigned,
0x00000303: (*State).IsGreaterThanUnsigned, OpIsGreaterThanUnsigned: (*State).IsGreaterThanUnsigned,
0x00000304: (*State).IsGreaterThanSigned, OpIsGreaterThanSigned: (*State).IsGreaterThanSigned,
0x00000305: (*State).IsLessThanOrEqualUnsigned, OpIsLessThanOrEqualUnsigned: (*State).IsLessThanOrEqualUnsigned,
0x00000306: (*State).IsLessThanOrEqualSigned, OpIsLessThanOrEqualSigned: (*State).IsLessThanOrEqualSigned,
0x00000307: (*State).IsGreaterThanOrEqualUnsigned, OpIsGreaterThanOrEqualUnsigned: (*State).IsGreaterThanOrEqualUnsigned,
0x00000308: (*State).IsGreaterThanOrEqualSigned, OpIsGreaterThanOrEqualSigned: (*State).IsGreaterThanOrEqualSigned,
0x00000400: (*State).Jump, OpJump: (*State).Jump,
0x00000401: (*State).JumpIfTrue, OpJumpIfTrue: (*State).JumpIfTrue,
0x00000402: (*State).JumpIfFalse, OpJumpIfFalse: (*State).JumpIfFalse,
} }
func NewInstruction(byteCode []byte) (*Instruction, error) { func NewInstruction(byteCode []byte) (*Instruction, error) {
@@ -111,6 +161,10 @@ func NewState(byteCodes [][]byte) (*State, error) {
instrs = append(instrs, instr) instrs = append(instrs, instr)
} }
instrs = append(instrs, &Instruction{
OpCode: OpReturn,
})
state.Functions = append(state.Functions, instrs) state.Functions = append(state.Functions, instrs)
} }
@@ -126,20 +180,26 @@ func (state *State) Function() []*Instruction {
} }
func (state *State) Execute() { func (state *State) Execute() {
state.prepare() state.setHandlers()
state.call(0) state.call(0)
state.Running = true
for len(state.Stack) > 0 && state.Error == nil{ for state.Running {
state.ProcessInstruction() state.ProcessInstruction()
} }
} }
func (state *State) prepare() { func (state *State) setError(err error) {
state.Error = err
state.Running = false
}
func (state *State) setHandlers() {
for _, fnc := range state.Functions { for _, fnc := range state.Functions {
for _, instr := range fnc { for _, instr := range fnc {
handler, found := OpHandlers[instr.OpCode] handler, found := OpHandlers[instr.OpCode]
if !found { if !found {
state.Error = fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode) state.setError(fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode))
return return
} }
@@ -150,12 +210,6 @@ func (state *State) prepare() {
func (state *State) ProcessInstruction() { func (state *State) ProcessInstruction() {
fnc := state.Function() fnc := state.Function()
if state.InstructionIndex >= int64(len(fnc)) {
state.ret()
return
}
instr := fnc[state.InstructionIndex] instr := fnc[state.InstructionIndex]
state.InstructionIndex += 1 state.InstructionIndex += 1
instr.opHandler(state, instr) instr.opHandler(state, instr)
@@ -168,20 +222,20 @@ func (state *State) ReadUnsigned(op *Operand) uint64 {
case FunctionMemoryIndex: case FunctionMemoryIndex:
if op.Value >= FunctionMemoryEntries { if op.Value >= FunctionMemoryEntries {
state.Error = fmt.Errorf("Invalid function memory index: %016x", op.Value) state.setError(fmt.Errorf("Invalid function memory index: %016x", op.Value))
return 0 return 0
} }
return state.StackFrame().FunctionMemory[op.Value] return state.StackFrame().FunctionMemory[op.Value]
case GlobalMemoryIndex: case GlobalMemoryIndex:
if op.Value >= GlobalMemoryEntries { if op.Value >= GlobalMemoryEntries {
state.Error = fmt.Errorf("Invalid global memory index: %016x", op.Value) state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
return 0 return 0
} }
return state.GlobalMemory[op.Value] return state.GlobalMemory[op.Value]
default: default:
state.Error = fmt.Errorf("Unknown operand type: 0x%02x", op.Type) state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
return 0 return 0
} }
} }
@@ -193,24 +247,24 @@ func (state *State) ReadSigned(op *Operand) int64 {
func (state *State) WriteUnsigned(op *Operand, value uint64) { func (state *State) WriteUnsigned(op *Operand, value uint64) {
switch op.Type { switch op.Type {
case Literal: case Literal:
state.Error = fmt.Errorf("Write to literal operand") state.setError(fmt.Errorf("Write to literal operand"))
case FunctionMemoryIndex: case FunctionMemoryIndex:
if op.Value >= FunctionMemoryEntries { if op.Value >= FunctionMemoryEntries {
state.Error = fmt.Errorf("Invalid function memory index: %016x", op.Value) state.setError(fmt.Errorf("Invalid function memory index: %016x", op.Value))
return return
} }
state.StackFrame().FunctionMemory[op.Value] = value state.StackFrame().FunctionMemory[op.Value] = value
case GlobalMemoryIndex: case GlobalMemoryIndex:
if op.Value >= GlobalMemoryEntries { if op.Value >= GlobalMemoryEntries {
state.Error = fmt.Errorf("Invalid global memory index: %016x", op.Value) state.setError(fmt.Errorf("Invalid global memory index: %016x", op.Value))
return return
} }
state.GlobalMemory[op.Value] = value state.GlobalMemory[op.Value] = value
default: default:
state.Error = fmt.Errorf("Unknown operand type: 0x%02x", op.Type) state.setError(fmt.Errorf("Unknown operand type: 0x%02x", op.Type))
} }
} }
@@ -228,7 +282,7 @@ func (state *State) Call(instr *Instruction) {
func (state *State) call(functionOffset int64) { func (state *State) call(functionOffset int64) {
if state.FunctionIndex+functionOffset >= int64(len(state.Functions)) { if state.FunctionIndex+functionOffset >= int64(len(state.Functions)) {
state.Error = fmt.Errorf("Invalid function call index: %d + %d = %d", state.FunctionIndex, functionOffset, state.FunctionIndex+functionOffset) state.setError(fmt.Errorf("Invalid function call index: %d + %d = %d", state.FunctionIndex, functionOffset, state.FunctionIndex+functionOffset))
return return
} }
@@ -249,6 +303,9 @@ func (state *State) ret() {
state.FunctionIndex = state.StackFrame().PreviousFunctionIndex state.FunctionIndex = state.StackFrame().PreviousFunctionIndex
state.InstructionIndex = state.StackFrame().PreviousInstructionIndex state.InstructionIndex = state.StackFrame().PreviousInstructionIndex
state.Stack = state.Stack[:len(state.Stack)-1] state.Stack = state.Stack[:len(state.Stack)-1]
if len(state.Stack) == 0 {
state.Running = false
}
} }
func (state *State) Move(instr *Instruction) { func (state *State) Move(instr *Instruction) {