diff --git a/pkg/compiler/inline_test.go b/pkg/compiler/inline_test.go index 46db2cece..328eec6ac 100644 --- a/pkg/compiler/inline_test.go +++ b/pkg/compiler/inline_test.go @@ -11,19 +11,31 @@ import ( "github.com/stretchr/testify/require" ) -func checkCallCount(t *testing.T, src string, expectedCall, expectedInitSlot int) { - v := vmAndCompile(t, src) +func checkCallCount(t *testing.T, src string, expectedCall, expectedInitSlot, expectedLocalsMain int) { + v, sp := vmAndCompileInterop(t, src) + + mainStart := -1 + for _, m := range sp.info.Methods { + if m.Name.Name == "main" { + mainStart = int(m.Range.Start) + } + } + require.True(t, mainStart >= 0) + ctx := v.Context() actualCall := 0 actualInitSlot := 0 - for op, _, err := ctx.Next(); ; op, _, err = ctx.Next() { + for op, param, err := ctx.Next(); ; op, param, err = ctx.Next() { require.NoError(t, err) switch op { case opcode.CALL, opcode.CALLL: actualCall++ case opcode.INITSLOT: actualInitSlot++ + if ctx.IP() == mainStart { + require.Equal(t, expectedLocalsMain, int(param[0])) + } } if ctx.IP() == ctx.LenInstr() { break @@ -47,75 +59,75 @@ func TestInline(t *testing.T) { t.Run("no return", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `inline.NoArgsNoReturn() return 1`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(1)) }) t.Run("has return, dropped", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `inline.NoArgsReturn1() return 2`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(2)) }) t.Run("drop twice", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `inline.DropInsideInline() return 42`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(42)) }) t.Run("no args return 1", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.NoArgsReturn1()`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(1)) }) t.Run("sum", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.Sum(1, 2)`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(3)) }) t.Run("sum squared (nested inline)", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.SumSquared(1, 2)`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(9)) }) t.Run("inline function in inline function parameter", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.Sum(inline.SumSquared(1, 2), inline.Sum(3, 4))`) - checkCallCount(t, src, 0, 1) + checkCallCount(t, src, 0, 1, 2) eval(t, src, big.NewInt(9+3+4)) }) t.Run("global name clash", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.GetSumSameName()`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(42)) }) t.Run("local name clash", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.Sum(inline.SumSquared(1, 2), sum(3, 4))`) - checkCallCount(t, src, 1, 2) + checkCallCount(t, src, 1, 2, 2) eval(t, src, big.NewInt(51)) }) t.Run("var args, empty", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.VarSum(11)`) - checkCallCount(t, src, 0, 1) + checkCallCount(t, src, 0, 1, 3) eval(t, src, big.NewInt(11)) }) t.Run("var args, direct", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.VarSum(11, 14, 17)`) - checkCallCount(t, src, 0, 1) + checkCallCount(t, src, 0, 1, 3) eval(t, src, big.NewInt(42)) }) t.Run("var args, array", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `arr := []int{14, 17} return inline.VarSum(11, arr...)`) - checkCallCount(t, src, 0, 1) + checkCallCount(t, src, 0, 1, 3) eval(t, src, big.NewInt(42)) }) t.Run("globals", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `return inline.Concat(Num)`) - checkCallCount(t, src, 0, 0) + checkCallCount(t, src, 0, 0, 0) eval(t, src, big.NewInt(221)) }) t.Run("locals, alias", func(t *testing.T) { src := fmt.Sprintf(srcTmpl, `num := 1; return inline.Concat(num)`) - checkCallCount(t, src, 0, 1) + checkCallCount(t, src, 0, 1, 1) eval(t, src, big.NewInt(221)) }) } diff --git a/pkg/compiler/vm_test.go b/pkg/compiler/vm_test.go index 6545dcf73..694975b86 100644 --- a/pkg/compiler/vm_test.go +++ b/pkg/compiler/vm_test.go @@ -69,6 +69,7 @@ func vmAndCompileInterop(t *testing.T, src string) (*vm.VM, *storagePlugin) { b, di, err := compiler.CompileWithDebugInfo("foo.go", strings.NewReader(src)) require.NoError(t, err) + storePlugin.info = di invokeMethod(t, testMainIdent, b, vm, di) return vm, storePlugin } @@ -93,6 +94,7 @@ func invokeMethod(t *testing.T, method string, script []byte, v *vm.VM, di *comp } type storagePlugin struct { + info *compiler.DebugInfo mem map[string][]byte interops map[uint32]func(v *vm.VM) error events []state.NotificationEvent