More private members

This commit is contained in:
Ian Gulliver
2021-11-16 15:27:30 -10:00
parent f39a856361
commit 7ab0aba088
3 changed files with 32 additions and 20 deletions

View File

@@ -5,18 +5,18 @@ import "bytes"
import "github.com/lunixbochs/struc" import "github.com/lunixbochs/struc"
import "github.com/pkg/errors" import "github.com/pkg/errors"
const InstructionBytes = 32
type Instruction struct { type Instruction struct {
OpCode OpCodeType OpCode OpCodeType
Reserved [4]byte Reserved [4]byte
Operand1 Operand Operand1 Operand
Operand2 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{} instr := &Instruction{}
reader := bytes.NewReader(byteCode) reader := bytes.NewReader(byteCode)
@@ -28,3 +28,25 @@ func NewInstruction(byteCode []byte) (*Instruction, error) {
return instr, nil 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
}

View File

@@ -1,8 +1,8 @@
package vm 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, OpNoOp: (*State).NoOp,
OpCall: (*State).Call, OpCall: (*State).Call,
OpReturn: (*State).Return, OpReturn: (*State).Return,

View File

@@ -23,20 +23,10 @@ func NewState(byteCodes [][]byte) (*State, error) {
state := &State{} state := &State{}
for i, byteCode := range byteCodes { for i, byteCode := range byteCodes {
instrs := []*Instruction{} instrs, err := NewInstructionsFromByteCode(byteCode)
for start := 0; start < len(byteCode); start += InstructionBytes {
chunk := byteCode[start : start+InstructionBytes]
instr, err := NewInstruction(chunk)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "At function index %d, byte offset %d", i, start) return nil, errors.Wrapf(err, "At function index %d", i)
} }
instrs = append(instrs, instr)
}
instrs = append(instrs, &Instruction{
OpCode: OpReturn,
})
state.functions = append(state.functions, instrs) state.functions = append(state.functions, instrs)
} }
@@ -70,7 +60,7 @@ func (state *State) setError(err error) {
func (state *State) setHandlers() { 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.setError(fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode)) state.setError(fmt.Errorf("Invalid OpCode: 0x%08x", instr.OpCode))
return return