Skip to content

Commit

Permalink
compiler: fix manifest method offset
Browse files Browse the repository at this point in the history
While optimizing jumps, old offsets should be compared
with the method offset before optimization, not with
the constantly changing value.
  • Loading branch information
fyrchik committed Oct 14, 2020
1 parent c72ecd1 commit 1f2d76a
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
9 changes: 6 additions & 3 deletions pkg/compiler/codegen.go
Original file line number Diff line number Diff line change
Expand Up @@ -1951,18 +1951,21 @@ func (c *codegen) writeJumps(b []byte) ([]byte, error) {
// Correct function ip range.
// Note: indices are sorted in increasing order.
for _, f := range c.funcs {
start, end := f.rng.Start, f.rng.End
loop:
for _, ind := range offsets {
switch {
case ind > int(f.rng.End):
break loop
case ind < int(f.rng.Start):
f.rng.Start -= longToShortRemoveCount
f.rng.End -= longToShortRemoveCount
start -= longToShortRemoveCount
end -= longToShortRemoveCount
case ind >= int(f.rng.Start):
f.rng.End -= longToShortRemoveCount
end -= longToShortRemoveCount
}
}
f.rng.Start = start
f.rng.End = end
}
return shortenJumps(b, offsets), nil
}
Expand Down
21 changes: 21 additions & 0 deletions pkg/compiler/function_call_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ package compiler_test
import (
"fmt"
"math/big"
"strings"
"testing"

"github.com/nspcc-dev/neo-go/pkg/compiler"
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
"github.com/stretchr/testify/require"
)

func TestSimpleFunctionCall(t *testing.T) {
Expand Down Expand Up @@ -269,3 +274,19 @@ func TestVariadicMethod(t *testing.T) {
}`
eval(t, src, big.NewInt(42))
}

func TestJumpOptimize(t *testing.T) {
src := `package foo
func Get1() int { return 1 }
func Get2() int { Get1(); Get1(); Get1(); Get1(); return Get1() }
func Get3() int { return Get2() }
func Main() int {
return Get3()
}`
b, di, err := compiler.CompileWithDebugInfo("", strings.NewReader(src))
require.NoError(t, err)
for _, mi := range di.Methods {
require.Equal(t, b[mi.Range.Start], byte(opcode.INITSLOT))
require.Equal(t, b[mi.Range.End], byte(opcode.RET))
}
}

0 comments on commit 1f2d76a

Please sign in to comment.