compiler: process last instructin in writeJumps

It is unlikely that we will emit a script with a JMP in the end,
but `writeJumps` must work correctly even in such case.
This commit is contained in:
Evgenii Stratonikov 2020-08-19 13:37:24 +03:00
parent cfa62e7051
commit 984aba3113
2 changed files with 11 additions and 1 deletions

View file

@ -1632,7 +1632,7 @@ func (c *codegen) resolveFuncDecls(f *ast.File, pkg *types.Package) {
func (c *codegen) writeJumps(b []byte) ([]byte, error) { func (c *codegen) writeJumps(b []byte) ([]byte, error) {
ctx := vm.NewContext(b) ctx := vm.NewContext(b)
var offsets []int var offsets []int
for op, _, err := ctx.Next(); err == nil && ctx.NextIP() < len(b); op, _, err = ctx.Next() { for op, _, err := ctx.Next(); err == nil && ctx.IP() < len(b); op, _, err = ctx.Next() {
switch op { switch op {
case opcode.JMP, opcode.JMPIFNOT, opcode.JMPIF, opcode.CALL, case opcode.JMP, opcode.JMPIFNOT, opcode.JMPIF, opcode.CALL,
opcode.JMPEQ, opcode.JMPNE, opcode.JMPEQ, opcode.JMPNE,

View file

@ -117,3 +117,13 @@ func TestWriteJumps(t *testing.T) {
require.Equal(t, expProg, buf) require.Equal(t, expProg, buf)
require.Equal(t, expFuncs, c.funcs) require.Equal(t, expFuncs, c.funcs)
} }
func TestWriteJumpsLastJump(t *testing.T) {
c := new(codegen)
c.l = []int{2}
prog := []byte{byte(opcode.JMP), 3, byte(opcode.RET), byte(opcode.JMPL), 0, 0, 0, 0}
expected := []byte{byte(opcode.JMP), 3, byte(opcode.RET), byte(opcode.JMP), 0xFF}
actual, err := c.writeJumps(prog)
require.NoError(t, err)
require.Equal(t, expected, actual)
}