v0.4.0 2fcc65d

gen.go RawHistoryFolder

1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3
4//go:build ignore
5
6package main
7
8import (
9	"bytes"
10	"fmt"
11	"go/format"
12	"log"
13	"os"
14	"strings"
15	"text/template"
16)
17
18const templateSymbols = `// Code generated by 'go generate' with gen.go. DO NOT EDIT.
19
20// SPDX-License-Identifier: Apache-2.0
21// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
22
23//go:build darwin || linux
24
25package fakecgo
26
27import (
28	"syscall"
29	"unsafe"
30)
31
32// setg_trampoline calls setg with the G provided
33func setg_trampoline(setg uintptr, G uintptr)
34
35//go:linkname memmove runtime.memmove
36func memmove(to, from unsafe.Pointer, n uintptr)
37
38// call5 takes fn the C function and 5 arguments and calls the function with those arguments
39func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr
40
41{{ range . -}}
42func {{.Name}}(
43{{- range .Args -}}
44	{{- if .Name -}}
45		{{.Name}} {{.Type}},
46	{{- end -}}
47{{- end -}}) {{.Return}} {
48	{{- if .Return -}}
49		{{- if eq .Return "unsafe.Pointer" -}}
50			ret :=
51		{{- else -}}
52			return {{.Return}}(
53		{{- end -}}
54	{{- end -}}
55call5({{.Name}}ABI0,
56{{- range .Args}}
57	{{- if .Name -}}
58		{{- if hasPrefix .Type "*" -}}
59			uintptr(unsafe.Pointer({{.Name}})),
60		{{- else -}}
61			uintptr({{.Name}}),
62		{{- end -}}
63	{{- else -}}
64		0,
65	{{- end -}}
66{{- end -}}
67	) {{/* end of call5 */}}
68{{- if .Return -}}
69	{{- if eq .Return "unsafe.Pointer"}}
70		// this indirection is to avoid go vet complaining about possible misuse of unsafe.Pointer
71		return *(*unsafe.Pointer)(unsafe.Pointer(&ret))
72	{{- else -}}
73		) {{/* end of cast */}}
74	{{- end -}}
75{{- end}}
76}
77
78{{end}} 
79{{- range . }}
80//go:linkname _{{.Name}} _{{.Name}}
81var _{{.Name}} uintptr
82var {{.Name}}ABI0 = uintptr(unsafe.Pointer(&_{{.Name}}))
83{{ end }}
84`
85
86const templateTrampolinesStubs = `// Code generated by 'go generate' with gen.go. DO NOT EDIT.
87
88// SPDX-License-Identifier: Apache-2.0
89// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
90
91//go:build darwin || linux
92
93#include "textflag.h"
94
95// these stubs are here because it is not possible to go:linkname directly the C functions on darwin arm64
96{{ range . }}
97TEXT _{{.Name}}(SB), NOSPLIT|NOFRAME, $0-0
98	JMP purego_{{.Name}}(SB)
99	RET
100{{ end -}}
101`
102
103type Arg struct {
104	Name string
105	Type string
106}
107
108type Symbol struct {
109	Name   string
110	Args   [5]Arg
111	Return string
112}
113
114var (
115	libcSymbols = []Symbol{
116		{"malloc", [5]Arg{{"size", "uintptr"}}, "unsafe.Pointer"},
117		{"free", [5]Arg{{"ptr", "unsafe.Pointer"}}, ""},
118		{"setenv", [5]Arg{{"name", "*byte"}, {"value", "*byte"}, {"overwrite", "int32"}}, "int32"},
119		{"unsetenv", [5]Arg{{"name", "*byte"}}, "int32"},
120		{"sigfillset", [5]Arg{{"set", "*sigset_t"}}, "int32"},
121		{"nanosleep", [5]Arg{{"ts", "*syscall.Timespec"}, {"rem", "*syscall.Timespec"}}, "int32"},
122		{"abort", [5]Arg{}, ""},
123	}
124	pthreadSymbols = []Symbol{
125		{"pthread_attr_init", [5]Arg{{"attr", "*pthread_attr_t"}}, "int32"},
126		{"pthread_create", [5]Arg{{"thread", "*pthread_t"}, {"attr", "*pthread_attr_t"}, {"start", "unsafe.Pointer"}, {"arg", "unsafe.Pointer"}}, "int32"},
127		{"pthread_detach", [5]Arg{{"thread", "pthread_t"}}, "int32"},
128		{"pthread_sigmask", [5]Arg{{"how", "sighow"}, {"ign", "*sigset_t"}, {"oset", "*sigset_t"}}, "int32"},
129		{"pthread_self", [5]Arg{}, "pthread_t"},
130		{"pthread_get_stacksize_np", [5]Arg{{"thread", "pthread_t"}}, "size_t"},
131		{"pthread_attr_getstacksize", [5]Arg{{"attr", "*pthread_attr_t"}, {"stacksize", "*size_t"}}, "int32"},
132		{"pthread_attr_setstacksize", [5]Arg{{"attr", "*pthread_attr_t"}, {"size", "size_t"}}, "int32"},
133		{"pthread_attr_destroy", [5]Arg{{"attr", "*pthread_attr_t"}}, "int32"},
134		{"pthread_mutex_lock", [5]Arg{{"mutex", "*pthread_mutex_t"}}, "int32"},
135		{"pthread_mutex_unlock", [5]Arg{{"mutex", "*pthread_mutex_t"}}, "int32"},
136		{"pthread_cond_broadcast", [5]Arg{{"cond", "*pthread_cond_t"}}, "int32"},
137		{"pthread_setspecific", [5]Arg{{"key", "pthread_key_t"}, {"value", "unsafe.Pointer"}}, "int32"},
138	}
139)
140
141var funcs = map[string]any{
142	"hasPrefix": strings.HasPrefix,
143}
144
145func run() error {
146	t, err := template.New("symbol.go").Funcs(funcs).Parse(templateSymbols)
147	if err != nil {
148		return err
149	}
150	f, err := os.Create("symbols.go")
151	defer f.Close()
152	if err != nil {
153		return err
154	}
155	allSymbols := append(append([]Symbol{}, libcSymbols...), pthreadSymbols...)
156	buf := new(bytes.Buffer)
157	if err := t.Execute(buf, allSymbols); err != nil {
158		return err
159	}
160	source, err := format.Source(buf.Bytes())
161	if err != nil {
162		return err
163	}
164	if _, err = f.Write(source); err != nil {
165		return err
166	}
167	t, err = template.New("trampolines_stubs.s").Funcs(funcs).Parse(templateTrampolinesStubs)
168	if err != nil {
169		return err
170	}
171	f, err = os.Create("trampolines_stubs.s")
172	defer f.Close()
173	if err != nil {
174		return err
175	}
176	if err := t.Execute(f, allSymbols); err != nil {
177		return err
178	}
179	for _, goos := range []string{"darwin", "linux"} {
180		f, err = os.Create(fmt.Sprintf("symbols_%s.go", goos))
181		defer f.Close()
182		if err != nil {
183			return err
184		}
185		f.WriteString(`// Code generated by 'go generate' with gen.go. DO NOT EDIT.
186
187// SPDX-License-Identifier: Apache-2.0
188// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
189
190package fakecgo
191
192`)
193		const importPragma = `//go:cgo_import_dynamic purego_%s %s "%s"` + "\n"
194		libcSO := "/usr/lib/libSystem.B.dylib"
195		pthreadSO := "/usr/lib/libSystem.B.dylib"
196		if goos == "linux" {
197			libcSO = "libc.so.6"
198			pthreadSO = "libpthread.so.0"
199		}
200		for _, sym := range libcSymbols {
201			f.WriteString(fmt.Sprintf(importPragma, sym.Name, sym.Name, libcSO))
202		}
203		for _, sym := range pthreadSymbols {
204			f.WriteString(fmt.Sprintf(importPragma, sym.Name, sym.Name, pthreadSO))
205		}
206	}
207	return nil
208}
209
210func main() {
211	if err := run(); err != nil {
212		log.Fatal(err)
213	}
214}

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