aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/syscall_windows_test.go
diff options
context:
space:
mode:
authorChangkun Ou <hi@changkun.de>2021-07-22 17:50:42 +0200
committerMatthew Dempsky <mdempsky@google.com>2021-08-19 17:30:19 +0000
commit0e598e7da42aea47b6b9d52c4292f202368d2f19 (patch)
treefc57d2f99791cf7361c0cb44f33872397c706f13 /src/runtime/syscall_windows_test.go
parent91e2e3b9030440713b59dcc7dd9deae71b18d9fc (diff)
downloadgo-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.go72
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)
+ }
+ })
}
}