docs: clarify raw syscall abi limits
- commit
- 5aa9aab010a59995380f17149879a36ab7d3f68f
- author
- brice · · 2026-04-13 10:18 UTC
- parent
- 5e114e1
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +12 -7
M syscall.go +6 -2
| @@ -52,13 +52,15 @@ func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uin | |||
| 52 | 52 | } | |
| 53 | 53 | ||
| 54 | 54 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |
| 55 | - | // There is an internal maximum number of arguments that SyscallN can take. It panics | |
| 56 | - | // when the maximum is exceeded. It returns the result and the libc error code if there is one. | |
| 55 | + | // There is an internal maximum number of arguments that SyscallN can take. | |
| 56 | + | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. | |
| 57 | + | // It panics when the maximum is exceeded. It returns the result and the libc error code if there is one. | |
| 57 | 58 | // | |
| 58 | 59 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | |
| 59 | 60 | // especially point 4. | |
| 60 | 61 | // | |
| 61 | 62 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | |
| 63 | + | // Use RegisterFunc instead when the target function mixes integer and floating-point arguments. | |
| 62 | 64 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | |
| 63 | 65 | // for an explanation of why that is. | |
| 64 | 66 | // | |
| @@ -85,6 +87,8 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||
| 85 | 87 | ||
| 86 | 88 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | |
| 87 | 89 | // It is designed for method-like calls where the first argument is always a receiver pointer. | |
| 90 | + | // It shares SyscallN's argument-placement limits and mixed integer/float restriction. | |
| 91 | + | // On 386 and arm, the total count including self is limited to 15 uintptr arguments. | |
| 88 | 92 | // This avoids the heap allocation that would occur with SyscallN(fn, append([]uintptr{self}, args...)...). | |
| 89 | 93 | // | |
| 90 | 94 | //go:uintptrescapes | |
| @@ -52,13 +52,15 @@ func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uin | |||||
| 52 | } | 52 | } | ||
| 53 | 53 | ||||
| 54 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | 54 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | ||
| 55 | - | // There is an internal maximum number of arguments that SyscallN can take. It panics | 55 | + | // There is an internal maximum number of arguments that SyscallN can take. |
| 56 | - | // when the maximum is exceeded. It returns the result and the libc error code if there is one. | 56 | + | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. |
| 57 | + | // It panics when the maximum is exceeded. It returns the result and the libc error code if there is one. | |||
| 57 | // | 58 | // | ||
| 58 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | 59 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | ||
| 59 | // especially point 4. | 60 | // especially point 4. | ||
| 60 | // | 61 | // | ||
| 61 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | 62 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | ||
| 63 | + | // Use RegisterFunc instead when the target function mixes integer and floating-point arguments. | |||
| 62 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | 64 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | ||
| 63 | // for an explanation of why that is. | 65 | // for an explanation of why that is. | ||
| 64 | // | 66 | // | ||
| @@ -85,6 +87,8 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||||
| 85 | 87 | ||||
| 86 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | 88 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | ||
| 87 | // It is designed for method-like calls where the first argument is always a receiver pointer. | 89 | // It is designed for method-like calls where the first argument is always a receiver pointer. | ||
| 90 | + | // It shares SyscallN's argument-placement limits and mixed integer/float restriction. | |||
| 91 | + | // On 386 and arm, the total count including self is limited to 15 uintptr arguments. | |||
| 88 | // This avoids the heap allocation that would occur with SyscallN(fn, append([]uintptr{self}, args...)...). | 92 | // This avoids the heap allocation that would occur with SyscallN(fn, append([]uintptr{self}, args...)...). | ||
| 89 | // | 93 | // | ||
| 90 | //go:uintptrescapes | 94 | //go:uintptrescapes | ||
M syscall_32bit.go +6 -5
| @@ -60,13 +60,14 @@ func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uin | |||
| 60 | 60 | } | |
| 61 | 61 | ||
| 62 | 62 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | |
| 63 | - | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. It panics when | |
| 64 | - | // the maximum is exceeded. It returns the result and the libc error code if there is one. | |
| 63 | + | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. | |
| 64 | + | // It panics when the maximum is exceeded. It returns the result and the libc error code if there is one. | |
| 65 | 65 | // | |
| 66 | 66 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | |
| 67 | 67 | // especially point 4. | |
| 68 | 68 | // | |
| 69 | 69 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | |
| 70 | + | // Use RegisterFunc instead when the target function mixes integer and floating-point arguments. | |
| 70 | 71 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | |
| 71 | 72 | // for an explanation of why that is. | |
| 72 | 73 | // | |
| @@ -93,9 +94,9 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||
| 93 | 94 | ||
| 94 | 95 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | |
| 95 | 96 | // It is designed for method-like calls where the first argument is always a receiver pointer. | |
| 96 | - | // It shares SyscallN's argument-placement limits, and the total count including self is | |
| 97 | - | // limited to 15 on 386 and arm. This avoids the heap allocation that would occur with | |
| 98 | - | // SyscallN(fn, append([]uintptr{self}, args...)...). | |
| 97 | + | // It shares SyscallN's argument-placement limits and mixed integer/float restriction. | |
| 98 | + | // On 386 and arm, the total count including self is limited to 15 uintptr arguments. | |
| 99 | + | // This avoids the heap allocation that would occur with SyscallN(fn, append([]uintptr{self}, args...)...). | |
| 99 | 100 | // | |
| 100 | 101 | //go:uintptrescapes | |
| 101 | 102 | func SyscallSelf(fn, self uintptr, args ...uintptr) (r1, r2, err uintptr) { | |
| @@ -60,13 +60,14 @@ func (s *syscall15Args) Set(fn uintptr, ints []uintptr, floats []uintptr, r8 uin | |||||
| 60 | } | 60 | } | ||
| 61 | 61 | ||||
| 62 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | 62 | // SyscallN takes fn, a C function pointer and a list of arguments as uintptr. | ||
| 63 | - | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. It panics when | 63 | + | // On 386 and arm, SyscallN supports at most 15 uintptr arguments. |
| 64 | - | // the maximum is exceeded. It returns the result and the libc error code if there is one. | 64 | + | // It panics when the maximum is exceeded. It returns the result and the libc error code if there is one. |
| 65 | // | 65 | // | ||
| 66 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | 66 | // In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer] | ||
| 67 | // especially point 4. | 67 | // especially point 4. | ||
| 68 | // | 68 | // | ||
| 69 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | 69 | // NOTE: SyscallN does not properly call functions that have both integer and float parameters. | ||
| 70 | + | // Use RegisterFunc instead when the target function mixes integer and floating-point arguments. | |||
| 70 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | 71 | // See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607 | ||
| 71 | // for an explanation of why that is. | 72 | // for an explanation of why that is. | ||
| 72 | // | 73 | // | ||
| @@ -93,9 +94,9 @@ func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) { | |||||
| 93 | 94 | ||||
| 94 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | 95 | // SyscallSelf is like SyscallN but efficiently prepends self to args without allocation. | ||
| 95 | // It is designed for method-like calls where the first argument is always a receiver pointer. | 96 | // It is designed for method-like calls where the first argument is always a receiver pointer. | ||
| 96 | - | // It shares SyscallN's argument-placement limits, and the total count including self is | 97 | + | // It shares SyscallN's argument-placement limits and mixed integer/float restriction. |
| 97 | - | // limited to 15 on 386 and arm. This avoids the heap allocation that would occur with | 98 | + | // On 386 and arm, the total count including self is limited to 15 uintptr arguments. |
| 98 | - | // SyscallN(fn, append([]uintptr{self}, args...)...). | 99 | + | // This avoids the heap allocation that would occur with SyscallN(fn, append([]uintptr{self}, args...)...). |
| 99 | // | 100 | // | ||
| 100 | //go:uintptrescapes | 101 | //go:uintptrescapes | ||
| 101 | func SyscallSelf(fn, self uintptr, args ...uintptr) (r1, r2, err uintptr) { | 102 | func SyscallSelf(fn, self uintptr, args ...uintptr) (r1, r2, err uintptr) { | ||