Files
subcoding/vm/instruction.go
2021-11-16 20:41:57 -10:00

53 lines
1.1 KiB
Go

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
}