From 2c063e538230859bce6df0cd77e77535115bc3cc Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Mon, 15 Nov 2021 20:24:20 -1000 Subject: [PATCH] Simplify main loop conditional --- main.go | 141 +++++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 99 insertions(+), 42 deletions(-) diff --git a/main.go b/main.go index f6473e2..6472a30 100644 --- a/main.go +++ b/main.go @@ -9,6 +9,7 @@ import "github.com/lunixbochs/struc" import "github.com/pkg/errors" type OperandType uint8 +type OpCodeType uint32 const ( Literal OperandType = 0 @@ -16,6 +17,54 @@ const ( 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 GlobalMemoryEntries = 16 const FunctionMemoryEntries = 16 @@ -29,7 +78,7 @@ type Operand struct { } type Instruction struct { - OpCode uint32 + OpCode OpCodeType Reserved [4]byte Operand1 Operand Operand2 Operand @@ -38,7 +87,8 @@ type Instruction struct { } type State struct { - Error error + Running bool + Error error Functions [][]*Instruction FunctionIndex int64 @@ -55,32 +105,32 @@ type StackFrame struct { FunctionMemory [FunctionMemoryEntries]uint64 } -var OpHandlers = map[uint32]OpHandler{ - 0x00000000: (*State).NoOp, - 0x00000001: (*State).Call, - 0x00000002: (*State).Return, +var OpHandlers = map[OpCodeType]OpHandler{ + OpNoOp: (*State).NoOp, + OpCall: (*State).Call, + OpReturn: (*State).Return, - 0x00000100: (*State).Move, + OpMove: (*State).Move, - 0x00000200: (*State).Add, - 0x00000201: (*State).Subtract, - 0x00000202: (*State).Multiply, - 0x00000203: (*State).DivideUnsigned, - 0x00000204: (*State).DivideSigned, + OpAdd: (*State).Add, + OpSubtract: (*State).Subtract, + OpMultiply: (*State).Multiply, + OpDivideUnsigned: (*State).DivideUnsigned, + OpDivideSigned: (*State).DivideSigned, - 0x00000300: (*State).IsEqual, - 0x00000301: (*State).IsLessThanUnsigned, - 0x00000302: (*State).IsLessThanSigned, - 0x00000303: (*State).IsGreaterThanUnsigned, - 0x00000304: (*State).IsGreaterThanSigned, - 0x00000305: (*State).IsLessThanOrEqualUnsigned, - 0x00000306: (*State).IsLessThanOrEqualSigned, - 0x00000307: (*State).IsGreaterThanOrEqualUnsigned, - 0x00000308: (*State).IsGreaterThanOrEqualSigned, + OpIsEqual: (*State).IsEqual, + OpIsLessThanUnsigned: (*State).IsLessThanUnsigned, + OpIsLessThanSigned: (*State).IsLessThanSigned, + OpIsGreaterThanUnsigned: (*State).IsGreaterThanUnsigned, + OpIsGreaterThanSigned: (*State).IsGreaterThanSigned, + OpIsLessThanOrEqualUnsigned: (*State).IsLessThanOrEqualUnsigned, + OpIsLessThanOrEqualSigned: (*State).IsLessThanOrEqualSigned, + OpIsGreaterThanOrEqualUnsigned: (*State).IsGreaterThanOrEqualUnsigned, + OpIsGreaterThanOrEqualSigned: (*State).IsGreaterThanOrEqualSigned, - 0x00000400: (*State).Jump, - 0x00000401: (*State).JumpIfTrue, - 0x00000402: (*State).JumpIfFalse, + OpJump: (*State).Jump, + OpJumpIfTrue: (*State).JumpIfTrue, + OpJumpIfFalse: (*State).JumpIfFalse, } func NewInstruction(byteCode []byte) (*Instruction, error) { @@ -111,6 +161,10 @@ func NewState(byteCodes [][]byte) (*State, error) { instrs = append(instrs, instr) } + instrs = append(instrs, &Instruction{ + OpCode: OpReturn, + }) + state.Functions = append(state.Functions, instrs) } @@ -126,20 +180,26 @@ func (state *State) Function() []*Instruction { } func (state *State) Execute() { - state.prepare() + state.setHandlers() state.call(0) + state.Running = true - for len(state.Stack) > 0 && state.Error == nil{ + for state.Running { 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 _, instr := range fnc { handler, found := OpHandlers[instr.OpCode] if !found { - state.Error = fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode) + state.setError(fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode)) return } @@ -150,12 +210,6 @@ func (state *State) prepare() { func (state *State) ProcessInstruction() { fnc := state.Function() - - if state.InstructionIndex >= int64(len(fnc)) { - state.ret() - return - } - instr := fnc[state.InstructionIndex] state.InstructionIndex += 1 instr.opHandler(state, instr) @@ -168,20 +222,20 @@ func (state *State) ReadUnsigned(op *Operand) uint64 { case FunctionMemoryIndex: 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 state.StackFrame().FunctionMemory[op.Value] case GlobalMemoryIndex: 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 state.GlobalMemory[op.Value] 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 } } @@ -193,24 +247,24 @@ func (state *State) ReadSigned(op *Operand) int64 { func (state *State) WriteUnsigned(op *Operand, value uint64) { switch op.Type { case Literal: - state.Error = fmt.Errorf("Write to literal operand") + state.setError(fmt.Errorf("Write to literal operand")) case FunctionMemoryIndex: 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 } state.StackFrame().FunctionMemory[op.Value] = value case GlobalMemoryIndex: 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 } state.GlobalMemory[op.Value] = value 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) { 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 } @@ -249,6 +303,9 @@ func (state *State) ret() { state.FunctionIndex = state.StackFrame().PreviousFunctionIndex state.InstructionIndex = state.StackFrame().PreviousInstructionIndex state.Stack = state.Stack[:len(state.Stack)-1] + if len(state.Stack) == 0 { + state.Running = false + } } func (state *State) Move(instr *Instruction) {