github.com/ebiten/purego@v0.0.0-20220525025155-0f6873f42222/syscall.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2022 The Ebiten Authors 3 4 //go:build darwin 5 // +build darwin 6 7 package purego 8 9 import "unsafe" 10 11 const maxArgs = 9 12 13 // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. 14 // There is an internal maximum number of arguments that SyscallN can take. It panics 15 // when the maximum is exceeded. It returns the result and the libc error code if there is one. 16 // 17 // NOTE: SyscallN does not properly call functions that have both integer and float parameters. 18 // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 19 // for an explanation of why that is. 20 // 21 // On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the 22 // stack. 23 func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { 24 if len(args) > maxArgs { 25 panic("too many arguments to SyscallN") 26 } 27 // add padding so there is no out-of-bounds slicing 28 var tmp [maxArgs]uintptr 29 copy(tmp[:], args) 30 if len(args) <= 6 { 31 // use the 6 argument version because 32 // gl.GenFramebuffersEXT would fail with the 9 version 33 // See https://github.com/hajimehoshi/ebiten/issues/2102#issuecomment-1134679352 34 return syscall_syscall6X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5]) 35 } 36 return syscall_syscall9X(fn, tmp[0], tmp[1], tmp[2], tmp[3], tmp[4], tmp[5], tmp[6], tmp[7], tmp[8]) 37 } 38 39 func callc(fn uintptr, args unsafe.Pointer) { 40 runtime_entersyscall() 41 runtime_libcCall(unsafe.Pointer(fn), args) 42 runtime_exitsyscall() 43 } 44 45 var syscall9XABI0 uintptr 46 47 func syscall9X() // implemented in assembly 48 49 func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) { 50 args := struct{ fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2, err uintptr }{ 51 fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, r1, r2, err} 52 callc(syscall9XABI0, unsafe.Pointer(&args)) 53 return args.r1, args.r2, args.err 54 }