1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3
4//go:build darwin || freebsd || linux || netbsd || windows
5
6package purego_test
7
8import (
9 "fmt"
10 "testing"
11
12 "github.com/bnema/purego"
13)
14
15func TestSyscallSelf(t *testing.T) {
16 sum2 := purego.NewCallback(func(self, a1 uintptr) uintptr { return self + a1 })
17 sum4 := purego.NewCallback(func(self, a1, a2, a3 uintptr) uintptr { return self + a1 + a2 + a3 })
18 triple := purego.NewCallback(func(self uintptr) uintptr { return self * 3 })
19
20 tests := []struct {
21 name string
22 fn uintptr
23 self uintptr
24 args []uintptr
25 want uintptr
26 }{
27 {"one arg", sum2, 10, []uintptr{20}, 30},
28 {"zero self", sum2, 0, []uintptr{42}, 42},
29 {"multiple args", sum4, 1, []uintptr{2, 3, 4}, 10},
30 {"no variadic args", triple, 7, nil, 21},
31 }
32 for _, tc := range tests {
33 t.Run(tc.name, func(t *testing.T) {
34 if r1, _, _ := purego.SyscallSelf(tc.fn, tc.self, tc.args...); r1 != tc.want {
35 t.Errorf("SyscallSelf returned %d, want %d", r1, tc.want)
36 }
37 })
38 }
39}
40
41func TestSyscallSelfPanics(t *testing.T) {
42 t.Run("nil fn", func(t *testing.T) {
43 defer func() {
44 if recover() == nil {
45 t.Error("expected panic for nil fn")
46 }
47 }()
48 purego.SyscallSelf(0, 1)
49 })
50
51 t.Run("too many args", func(t *testing.T) {
52 defer func() {
53 if got := fmt.Sprint(recover()); got != "purego: too many arguments to SyscallSelf" {
54 t.Errorf("unexpected panic: %s", got)
55 }
56 }()
57 fn := purego.NewCallback(func(uintptr) uintptr { return 0 })
58 purego.SyscallSelf(fn, 1, make([]uintptr, purego.MaxArgs)...)
59 })
60}
61
62func TestSyscallSelfAllocs(t *testing.T) {
63 fn := purego.NewCallback(func(self, a1, a2 uintptr) uintptr { return self + a1 + a2 })
64 directAllocs := testing.AllocsPerRun(100, func() { purego.SyscallN(fn, 1, 2, 3) })
65 selfAllocs := testing.AllocsPerRun(100, func() { purego.SyscallSelf(fn, 1, 2, 3) })
66 if selfAllocs > directAllocs {
67 t.Fatalf("SyscallSelf allocs = %v, SyscallN allocs = %v", selfAllocs, directAllocs)
68 }
69}