From 7ab0aba088c0c654e64773d62be48ba660d6cb85 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Tue, 16 Nov 2021 15:27:30 -1000 Subject: [PATCH] More private members --- instruction.go | 30 ++++++++++++++++++++++++++---- ophandler.go | 4 ++-- state.go | 18 ++++-------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/instruction.go b/instruction.go index 40dace8..fffddba 100644 --- a/instruction.go +++ b/instruction.go @@ -5,18 +5,18 @@ import "bytes" import "github.com/lunixbochs/struc" import "github.com/pkg/errors" -const InstructionBytes = 32 - type Instruction struct { OpCode OpCodeType Reserved [4]byte Operand1 Operand Operand2 Operand - opHandler OpHandler `struc:"skip"` + opHandler opHandler `struc:"skip"` } -func NewInstruction(byteCode []byte) (*Instruction, error) { +const instructionBytes = 32 + +func NewInstructionFromByteCode(byteCode []byte) (*Instruction, error) { instr := &Instruction{} reader := bytes.NewReader(byteCode) @@ -28,3 +28,25 @@ func NewInstruction(byteCode []byte) (*Instruction, error) { return instr, nil } + +func NewInstructionsFromByteCode(byteCode []byte) ([]*Instruction, error) { + instrs := []*Instruction{} + + for start := 0; start < len(byteCode); start += instructionBytes { + chunk := byteCode[start : start+instructionBytes] + instr, err := NewInstructionFromByteCode(chunk) + if err != nil { + return nil, errors.Wrapf(err, "At byte offset %d", start) + } + 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 +} diff --git a/ophandler.go b/ophandler.go index 0dc266a..e35d8b7 100644 --- a/ophandler.go +++ b/ophandler.go @@ -1,8 +1,8 @@ package vm -type OpHandler func(*State, *Instruction) +type opHandler func(*State, *Instruction) -var OpHandlers = map[OpCodeType]OpHandler{ +var opHandlers = map[OpCodeType]opHandler{ OpNoOp: (*State).NoOp, OpCall: (*State).Call, OpReturn: (*State).Return, diff --git a/state.go b/state.go index 2fd02c7..5fc263d 100644 --- a/state.go +++ b/state.go @@ -23,21 +23,11 @@ func NewState(byteCodes [][]byte) (*State, error) { state := &State{} for i, byteCode := range byteCodes { - instrs := []*Instruction{} - - for start := 0; start < len(byteCode); start += InstructionBytes { - chunk := byteCode[start : start+InstructionBytes] - instr, err := NewInstruction(chunk) - if err != nil { - return nil, errors.Wrapf(err, "At function index %d, byte offset %d", i, start) - } - instrs = append(instrs, instr) + instrs, err := NewInstructionsFromByteCode(byteCode) + if err != nil { + return nil, errors.Wrapf(err, "At function index %d", i) } - instrs = append(instrs, &Instruction{ - OpCode: OpReturn, - }) - state.functions = append(state.functions, instrs) } @@ -70,7 +60,7 @@ func (state *State) setError(err error) { func (state *State) setHandlers() { for _, fnc := range state.functions { for _, instr := range fnc { - handler, found := OpHandlers[instr.OpCode] + handler, found := opHandlers[instr.OpCode] if !found { state.setError(fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode)) return