package vm import "bytes" import "github.com/lunixbochs/struc" import "github.com/pkg/errors" type Instruction struct { OpCode OpCodeType Reserved [4]byte Operand1 Operand Operand2 Operand opHandler opHandler `struc:"skip"` } const instructionBytes = 32 func NewInstructionFromByteCode(byteCode []byte) (*Instruction, error) { instr := &Instruction{} reader := bytes.NewReader(byteCode) err := struc.Unpack(reader, instr) if err != nil { return nil, errors.Wrap(err, "Error decoding instruction") } 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 }