v0.11.0-alpha.10 749871c

syscall_32bit.go RawHistoryFolder

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3
4//go:build (386 || arm) && (freebsd || linux || netbsd || windows)
5
6package purego
7
8import (
9	"runtime"
10	"structs"
11	"unsafe"
12)
13
14const (
15	maxArgs = 32
16)
17
18// syscallArgs is the argument block handed to the syscall15 trampoline. On
19// platforms that go through internal/cgo it is passed to C as a
20// struct syscallArgs, so its layout must match the C ABI.
21type syscallArgs struct {
22	_ structs.HostLayout
23
24	fn, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15                uintptr
25	a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, a29, a30, a31, a32 uintptr
26	f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16               uintptr
27	arm64_r8                                                                            uintptr
28}
29
30func syscall_SyscallN(fn uintptr, sysargs []uintptr, floats []uintptr, r8 uintptr) *syscallArgs {
31	s := thePool.Get().(*syscallArgs)
32	*s = syscallArgs{
33		fn: fn,
34		a1: sysargs[0], a2: sysargs[1], a3: sysargs[2], a4: sysargs[3],
35		a5: sysargs[4], a6: sysargs[5], a7: sysargs[6], a8: sysargs[7],
36		a9: sysargs[8], a10: sysargs[9], a11: sysargs[10], a12: sysargs[11],
37		a13: sysargs[12], a14: sysargs[13], a15: sysargs[14], a16: sysargs[15],
38		a17: sysargs[16], a18: sysargs[17], a19: sysargs[18], a20: sysargs[19],
39		a21: sysargs[20], a22: sysargs[21], a23: sysargs[22], a24: sysargs[23],
40		a25: sysargs[24], a26: sysargs[25], a27: sysargs[26], a28: sysargs[27],
41		a29: sysargs[28], a30: sysargs[29], a31: sysargs[30], a32: sysargs[31],
42		f1: floats[0], f2: floats[1], f3: floats[2], f4: floats[3],
43		f5: floats[4], f6: floats[5], f7: floats[6], f8: floats[7],
44		f9: floats[8], f10: floats[9], f11: floats[10], f12: floats[11],
45		f13: floats[12], f14: floats[13], f15: floats[14], f16: floats[15],
46		arm64_r8: r8,
47	}
48	runtime_cgocall(syscallXABI0, unsafe.Pointer(s))
49	return s
50}
51
52// SyscallN takes fn, a C function pointer and a list of arguments as uintptr.
53// There is an internal maximum number of arguments that SyscallN can take. It panics
54// when the maximum is exceeded. It returns the result and the libc error code if there is one.
55//
56// In order to call this function properly make sure to follow all the rules specified in [unsafe.Pointer]
57// especially point 4.
58//
59// NOTE: SyscallN does not properly call functions that have both integer and float parameters.
60// See discussion comment https://github.com/ebiten/purego/pull/1#issuecomment-1128057607
61// for an explanation of why that is.
62//
63// On amd64, if there are more than 8 floats the 9th and so on will be placed incorrectly on the
64// stack.
65//
66// The pragma go:nosplit is not needed at this function declaration because it uses go:uintptrescapes
67// which forces all the objects that the uintptrs point to onto the heap where a stack split won't affect
68// their memory location.
69//
70//go:uintptrescapes
71func SyscallN(fn uintptr, args ...uintptr) (r1, r2, err uintptr) {
72	if fn == 0 {
73		panic("purego: fn is nil")
74	}
75	if len(args) > maxArgs {
76		panic("purego: too many arguments to SyscallN")
77	}
78
79	// Windows uses syscall.SyscallN in syscall_windows.go.
80	if runtime.GOOS == "windows" {
81		return syscall_syscallN(fn, args...)
82	}
83
84	// Add padding so there is no out-of-bounds slicing.
85	var tmp [maxArgs]uintptr
86	copy(tmp[:], args)
87	var floats [16]uintptr
88	copy(floats[:], tmp[:16])
89	s := syscall_SyscallN(fn, tmp[:], floats[:], 0)
90	defer thePool.Put(s)
91	return s.a1, s.a2, s.a3
92}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close