Split out the loader from the VM
This commit is contained in:
54
load/load.go
Normal file
54
load/load.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package load
|
||||
|
||||
import "bytes"
|
||||
|
||||
import "github.com/firestuff/subcoding/vm"
|
||||
import "github.com/lunixbochs/struc"
|
||||
import "github.com/pkg/errors"
|
||||
|
||||
const instructionBytes = 32
|
||||
|
||||
func Load(byteCodes [][]byte) ([][]*vm.Instruction, error) {
|
||||
fncs := [][]*vm.Instruction{}
|
||||
|
||||
for i, byteCode := range byteCodes {
|
||||
instrs, err := loadFunction(byteCode)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "At function index %d", i)
|
||||
}
|
||||
|
||||
fncs = append(fncs, instrs)
|
||||
}
|
||||
|
||||
return fncs, nil
|
||||
}
|
||||
|
||||
func loadFunction(byteCode []byte) ([]*vm.Instruction, error) {
|
||||
instrs := []*vm.Instruction{}
|
||||
|
||||
for start := 0; start < len(byteCode); start += instructionBytes {
|
||||
chunk := byteCode[start : start+instructionBytes]
|
||||
|
||||
instr, err := loadInstruction(chunk)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "At byte offset %d", start)
|
||||
}
|
||||
|
||||
instrs = append(instrs, instr)
|
||||
}
|
||||
|
||||
return instrs, nil
|
||||
}
|
||||
|
||||
func loadInstruction(byteCode []byte) (*vm.Instruction, error) {
|
||||
instr := &vm.Instruction{}
|
||||
|
||||
reader := bytes.NewReader(byteCode)
|
||||
|
||||
err := struc.Unpack(reader, instr)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Error decoding instruction")
|
||||
}
|
||||
|
||||
return instr, nil
|
||||
}
|
||||
Reference in New Issue
Block a user