vm: beautify PrintOps() output for JMP* instructions

This commit is contained in:
Evgenii Stratonikov 2020-06-26 19:27:14 +03:00
parent 709f656bcf
commit 82417499d7

View file

@ -197,9 +197,18 @@ func (v *VM) PrintOps() {
var desc = ""
if parameter != nil {
switch instr {
case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT, opcode.CALL:
offset := int16(binary.LittleEndian.Uint16(parameter))
desc = fmt.Sprintf("%d (%d/%x)", ctx.ip+int(offset), offset, parameter)
case opcode.JMP, opcode.JMPIF, opcode.JMPIFNOT, opcode.CALL,
opcode.JMPEQ, opcode.JMPNE,
opcode.JMPGT, opcode.JMPGE, opcode.JMPLE, opcode.JMPLT,
opcode.JMPL, opcode.JMPIFL, opcode.JMPIFNOTL, opcode.CALLL,
opcode.JMPEQL, opcode.JMPNEL,
opcode.JMPGTL, opcode.JMPGEL, opcode.JMPLEL, opcode.JMPLTL:
offset, rOffset, err := v.calcJumpOffset(ctx, parameter)
if err != nil {
desc = fmt.Sprintf("ERROR: %v", err)
} else {
desc = fmt.Sprintf("%d (%d/%x)", offset, rOffset, parameter)
}
case opcode.PUSHA:
offset := int32(binary.LittleEndian.Uint32(parameter))
desc = fmt.Sprintf("%d (%x)", offset, parameter)
@ -1424,6 +1433,14 @@ func (v *VM) jumpIf(ctx *Context, offset int, cond bool) {
// parameter should have length either 1 or 4 and
// is interpreted as little-endian.
func (v *VM) getJumpOffset(ctx *Context, parameter []byte) int {
offset, _, err := v.calcJumpOffset(ctx, parameter)
if err != nil {
panic(err)
}
return offset
}
func (v *VM) calcJumpOffset(ctx *Context, parameter []byte) (int, int, error) {
var rOffset int32
switch l := len(parameter); l {
case 1:
@ -1431,14 +1448,14 @@ func (v *VM) getJumpOffset(ctx *Context, parameter []byte) int {
case 4:
rOffset = int32(binary.LittleEndian.Uint32(parameter))
default:
panic(fmt.Sprintf("invalid JMP* parameter length: %d", l))
return 0, 0, fmt.Errorf("invalid JMP* parameter length: %d", l)
}
offset := ctx.ip + int(rOffset)
if offset < 0 || offset > len(ctx.prog) {
panic(fmt.Sprintf("JMP: invalid offset %d ip at %d", offset, ctx.ip))
return 0, 0, fmt.Errorf("invalid offset %d ip at %d", offset, ctx.ip)
}
return offset
return offset, int(rOffset), nil
}
// CheckMultisigPar checks if sigs contains sufficient valid signatures.