diff options
| author | Changkun Ou <hi@changkun.de> | 2021-07-22 17:50:42 +0200 |
|---|---|---|
| committer | Matthew Dempsky <mdempsky@google.com> | 2021-08-19 17:30:19 +0000 |
| commit | 0e598e7da42aea47b6b9d52c4292f202368d2f19 (patch) | |
| tree | fc57d2f99791cf7361c0cb44f33872397c706f13 /src/runtime/syscall_windows_test.go | |
| parent | 91e2e3b9030440713b59dcc7dd9deae71b18d9fc (diff) | |
| download | go-0e598e7da42aea47b6b9d52c4292f202368d2f19.tar.xz | |
syscall: add SyscallN
This CL adds a new syscall.SyscallN API.
The proposal discussion also suggests the API should not only for
Windows but other platforms. However, the existing API set already
contain differences between platforms, hence the CL only implements
the Windows platform.
Moreover, although the API offers variadic parameters, the permitted
parameters remains up to a limit, which is selected as 42, and arguably
large enough.
Fixes #46552
Change-Id: I66b49988a304d9fc178c7cd5de46d0b75e167a4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/336550
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Matthew Dempsky <mdempsky@google.com>
Trust: Jason A. Donenfeld <Jason@zx2c4.com>
Diffstat (limited to 'src/runtime/syscall_windows_test.go')
| -rw-r--r-- | src/runtime/syscall_windows_test.go | 72 |
1 files changed, 42 insertions, 30 deletions
diff --git a/src/runtime/syscall_windows_test.go b/src/runtime/syscall_windows_test.go index e3f772ac4b..235c79f68f 100644 --- a/src/runtime/syscall_windows_test.go +++ b/src/runtime/syscall_windows_test.go @@ -759,7 +759,7 @@ uintptr_t cfunc(callback f, uintptr_t n) { } } -func TestSyscall18(t *testing.T) { +func TestSyscallN(t *testing.T) { if _, err := exec.LookPath("gcc"); err != nil { t.Skip("skipping test: gcc is missing") } @@ -767,40 +767,52 @@ func TestSyscall18(t *testing.T) { t.Skipf("skipping test: GOARCH=%s", runtime.GOARCH) } - const src = ` -#include <stdint.h> -#include <windows.h> + for arglen := 0; arglen <= runtime.MaxArgs; arglen++ { + arglen := arglen + t.Run(fmt.Sprintf("arg-%d", arglen), func(t *testing.T) { + t.Parallel() + args := make([]string, arglen) + rets := make([]string, arglen+1) + params := make([]uintptr, arglen) + for i := range args { + args[i] = fmt.Sprintf("int a%d", i) + rets[i] = fmt.Sprintf("(a%d == %d)", i, i) + params[i] = uintptr(i) + } + rets[arglen] = "1" // for arglen == 0 -int cfunc( int a1, int a2, int a3, int a4, int a5, int a6, int a7, int a8, int a9, - int a10, int a11, int a12, int a13, int a14, int a15, int a16, int a17, int a18) { - return 1; -} -` - tmpdir := t.TempDir() + src := fmt.Sprintf(` + #include <stdint.h> + #include <windows.h> + int cfunc(%s) { return %s; }`, strings.Join(args, ", "), strings.Join(rets, " && ")) - srcname := "mydll.c" - err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0) - if err != nil { - t.Fatal(err) - } - outname := "mydll.dll" - cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", outname, srcname) - cmd.Dir = tmpdir - out, err := cmd.CombinedOutput() - if err != nil { - t.Fatalf("failed to build dll: %v - %v", err, string(out)) - } - dllpath := filepath.Join(tmpdir, outname) + tmpdir := t.TempDir() - dll := syscall.MustLoadDLL(dllpath) - defer dll.Release() + srcname := "mydll.c" + err := os.WriteFile(filepath.Join(tmpdir, srcname), []byte(src), 0) + if err != nil { + t.Fatal(err) + } + outname := "mydll.dll" + cmd := exec.Command("gcc", "-shared", "-s", "-Werror", "-o", outname, srcname) + cmd.Dir = tmpdir + out, err := cmd.CombinedOutput() + if err != nil { + t.Fatalf("failed to build dll: %v\n%s", err, out) + } + dllpath := filepath.Join(tmpdir, outname) - proc := dll.MustFindProc("cfunc") + dll := syscall.MustLoadDLL(dllpath) + defer dll.Release() - // proc.Call() will call Syscall18() internally. - r, _, err := proc.Call(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18) - if r != 1 { - t.Errorf("got %d want 1 (err=%v)", r, err) + proc := dll.MustFindProc("cfunc") + + // proc.Call() will call SyscallN() internally. + r, _, err := proc.Call(params...) + if r != 1 { + t.Errorf("got %d want 1 (err=%v)", r, err) + } + }) } } |
