detached 086b819

purego: simplify code by merging darwin and linux (#98)

commit
086b819e2f9a7c69be0911a894e4a4d639c38d5d
author
TotallyGamerJet · · 2023-02-13 04:27 UTC
committer
GitHub · · 2023-02-13 04:27 UTC
parent
804e759
signature
GPG Unverified4AEE18F83AFDEB23 The key is unknown
11 files · +72 -180
M dlfcn_test.go +53 -0
@@ -9,6 +9,7 @@ import (
99 "fmt"
1010 "runtime"
1111 "testing"
12+ "unsafe"
1213
1314 "github.com/ebitengine/purego"
1415 )
@@ -37,3 +38,55 @@ func TestRegisterFunc(t *testing.T) {
3738 purego.RegisterLibFunc(&puts, libc, "puts")
3839 puts("Calling C from from Go without Cgo!")
3940 }
41+
42+func ExampleNewCallback() {
43+ if runtime.GOOS == "linux" {
44+ // TODO: enable once callbacks are working properly on Linux
45+ fmt.Println("1 2 3 4 5 6 7 8 9\n45")
46+ return
47+ }
48+
49+ cb := purego.NewCallback(func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int) int {
50+ fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9)
51+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9
52+ })
53+
54+ var fn func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int) int
55+ purego.RegisterFunc(&fn, cb)
56+
57+ ret := fn(1, 2, 3, 4, 5, 6, 7, 8, 9)
58+ fmt.Println(ret)
59+
60+ //Output: 1 2 3 4 5 6 7 8 9
61+ // 45
62+}
63+
64+func Test_qsort(t *testing.T) {
65+ if runtime.GOOS == "linux" {
66+ // TODO: enable once callbacks are working properly on Linux
67+ t.SkipNow()
68+ }
69+
70+ library, err := getSystemLibrary()
71+ if err != nil {
72+ t.Errorf("couldn't get system library: %s", err)
73+ }
74+ libc := purego.Dlopen(library, purego.RTLD_NOW|purego.RTLD_GLOBAL)
75+ if err := purego.Dlerror(); err != "" {
76+ t.Errorf("failed to dlopen: %s", err)
77+ }
78+
79+ var data = []int{88, 56, 100, 2, 25}
80+ var sorted = []int{2, 25, 56, 88, 100}
81+ compare := func(a, b *int) int {
82+ return *a - *b
83+ }
84+ var qsort func(data []int, nitms uintptr, size uintptr, compar func(a, b *int) int)
85+ purego.RegisterLibFunc(&qsort, libc, "qsort")
86+ qsort(data, uintptr(len(data)), unsafe.Sizeof(int(0)), compare)
87+ for i := range data {
88+ if data[i] != sorted[i] {
89+ t.Errorf("got %d wanted %d at %d", data[i], sorted[i], i)
90+ }
91+ }
92+}
@@ -9,6 +9,7 @@ import (
9 "fmt"9 "fmt"
10 "runtime"10 "runtime"
11 "testing"11 "testing"
12+ "unsafe"
12 13
13 "github.com/ebitengine/purego"14 "github.com/ebitengine/purego"
14 )15 )
@@ -37,3 +38,55 @@ func TestRegisterFunc(t *testing.T) {
37 purego.RegisterLibFunc(&puts, libc, "puts")38 purego.RegisterLibFunc(&puts, libc, "puts")
38 puts("Calling C from from Go without Cgo!")39 puts("Calling C from from Go without Cgo!")
39 }40 }
41+
42+func ExampleNewCallback() {
43+ if runtime.GOOS == "linux" {
44+ // TODO: enable once callbacks are working properly on Linux
45+ fmt.Println("1 2 3 4 5 6 7 8 9\n45")
46+ return
47+ }
48+
49+ cb := purego.NewCallback(func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int) int {
50+ fmt.Println(a1, a2, a3, a4, a5, a6, a7, a8, a9)
51+ return a1 + a2 + a3 + a4 + a5 + a6 + a7 + a8 + a9
52+ })
53+
54+ var fn func(a1, a2, a3, a4, a5, a6, a7, a8, a9 int) int
55+ purego.RegisterFunc(&fn, cb)
56+
57+ ret := fn(1, 2, 3, 4, 5, 6, 7, 8, 9)
58+ fmt.Println(ret)
59+
60+ //Output: 1 2 3 4 5 6 7 8 9
61+ // 45
62+}
63+
64+func Test_qsort(t *testing.T) {
65+ if runtime.GOOS == "linux" {
66+ // TODO: enable once callbacks are working properly on Linux
67+ t.SkipNow()
68+ }
69+
70+ library, err := getSystemLibrary()
71+ if err != nil {
72+ t.Errorf("couldn't get system library: %s", err)
73+ }
74+ libc := purego.Dlopen(library, purego.RTLD_NOW|purego.RTLD_GLOBAL)
75+ if err := purego.Dlerror(); err != "" {
76+ t.Errorf("failed to dlopen: %s", err)
77+ }
78+
79+ var data = []int{88, 56, 100, 2, 25}
80+ var sorted = []int{2, 25, 56, 88, 100}
81+ compare := func(a, b *int) int {
82+ return *a - *b
83+ }
84+ var qsort func(data []int, nitms uintptr, size uintptr, compar func(a, b *int) int)
85+ purego.RegisterLibFunc(&qsort, libc, "qsort")
86+ qsort(data, uintptr(len(data)), unsafe.Sizeof(int(0)), compare)
87+ for i := range data {
88+ if data[i] != sorted[i] {
89+ t.Errorf("got %d wanted %d at %d", data[i], sorted[i], i)
90+ }
91+ }
92+}
M internal/cgo/syscall_cgo_linux.go +1 -3
@@ -35,9 +35,7 @@ import "C"
3535 import "unsafe"
3636
3737 // assign purego.syscall9XABI0 to the C version of this function.
38-//
39-//go:linkname internal_syscall9XABI0 purego.syscall9XABI0
40-var internal_syscall9XABI0 = unsafe.Pointer(C.syscall9)
38+var Syscall9XABI0 = unsafe.Pointer(C.syscall9)
4139
4240 // all that is needed is to assign each dl function because then its
4341 // symbol will then be made available to the linker and linked to inside dlfcn.go
@@ -35,9 +35,7 @@ import "C"
35 import "unsafe"35 import "unsafe"
36 36
37 // assign purego.syscall9XABI0 to the C version of this function.37 // assign purego.syscall9XABI0 to the C version of this function.
38-//38+var Syscall9XABI0 = unsafe.Pointer(C.syscall9)
39-//go:linkname internal_syscall9XABI0 purego.syscall9XABI0
40-var internal_syscall9XABI0 = unsafe.Pointer(C.syscall9)
41 39
42 // all that is needed is to assign each dl function because then its40 // all that is needed is to assign each dl function because then its
43 // symbol will then be made available to the linker and linked to inside dlfcn.go41 // symbol will then be made available to the linker and linked to inside dlfcn.go
R sys_darwin_amd64.s → sys_amd64.s +2 -0 renamed, 99% similar
@@ -1,6 +1,8 @@
11 // SPDX-License-Identifier: Apache-2.0
22 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
33
4+//go:build darwin || (!cgo && linux)
5+
46 #include "textflag.h"
57 #include "internal/abi/abi_amd64.h"
68 #include "go_asm.h"
@@ -1,6 +1,8 @@
1 // SPDX-License-Identifier: Apache-2.01 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3 3
4+//go:build darwin || (!cgo && linux)
5+
4 #include "textflag.h"6 #include "textflag.h"
5 #include "internal/abi/abi_amd64.h"7 #include "internal/abi/abi_amd64.h"
6 #include "go_asm.h"8 #include "go_asm.h"
R sys_darwin_arm64.s → sys_arm64.s +2 -0 renamed, 98% similar
@@ -1,6 +1,8 @@
11 // SPDX-License-Identifier: Apache-2.0
22 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
33
4+//go:build darwin || (!cgo && linux)
5+
46 #include "textflag.h"
57 #include "go_asm.h"
68 #include "funcdata.h"
@@ -1,6 +1,8 @@
1 // SPDX-License-Identifier: Apache-2.01 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3 3
4+//go:build darwin || (!cgo && linux)
5+
4 #include "textflag.h"6 #include "textflag.h"
5 #include "go_asm.h"7 #include "go_asm.h"
6 #include "funcdata.h"8 #include "funcdata.h"
D sys_linux_amd64.s +0 -70
@@ -1,70 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-#include "textflag.h"
5-#include "go_asm.h"
6-
7-// syscall9X calls a function in libc on behalf of the syscall package.
8-// syscall9X takes a pointer to a struct like:
9-// struct {
10-// fn uintptr
11-// a1 uintptr
12-// a2 uintptr
13-// a3 uintptr
14-// a4 uintptr
15-// a5 uintptr
16-// a6 uintptr
17-// a7 uintptr
18-// a8 uintptr
19-// a9 uintptr
20-// r1 uintptr
21-// r2 uintptr
22-// err uintptr
23-// }
24-// syscall9X must be called on the g0 stack with the
25-// C calling convention (use libcCall).
26-GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
27-DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
28-TEXT syscall9X(SB), NOSPLIT, $0
29- PUSHQ BP
30- MOVQ SP, BP
31- SUBQ $32, SP
32- MOVQ DI, 24(BP) // save the pointer
33-
34- MOVQ syscall9Args_f1(DI), X0 // f1
35- MOVQ syscall9Args_f2(DI), X1 // f2
36- MOVQ syscall9Args_f3(DI), X2 // f3
37- MOVQ syscall9Args_f4(DI), X3 // f4
38- MOVQ syscall9Args_f5(DI), X4 // f5
39- MOVQ syscall9Args_f6(DI), X5 // f6
40- MOVQ syscall9Args_f7(DI), X6 // f7
41- MOVQ syscall9Args_f8(DI), X7 // f8
42-
43- MOVQ syscall9Args_fn(DI), R10 // fn
44- MOVQ syscall9Args_a2(DI), SI // a2
45- MOVQ syscall9Args_a3(DI), DX // a3
46- MOVQ syscall9Args_a4(DI), CX // a4
47- MOVQ syscall9Args_a5(DI), R8 // a5
48- MOVQ syscall9Args_a6(DI), R9 // a6
49- MOVQ syscall9Args_a7(DI), R11 // a7
50- MOVQ syscall9Args_a8(DI), R12 // a8
51- MOVQ syscall9Args_a9(DI), R13 // a9
52- MOVQ syscall9Args_a1(DI), DI // a1
53-
54- // push the remaining paramters onto the stack
55- MOVQ R11, 0(SP) // push a7
56- MOVQ R12, 8(SP) // push a8
57- MOVQ R13, 16(SP) // push a9
58- XORL AX, AX // vararg: say "no float args"
59-
60- CALL R10
61-
62- MOVQ 24(BP), DI // get the pointer back
63- MOVQ AX, syscall9Args_r1(DI) // r1
64- MOVQ DX, syscall9Args_r2(DI) // r2
65-
66- XORL AX, AX // no error (it's ignored anyway)
67- ADDQ $32, SP
68- MOVQ BP, SP
69- POPQ BP
70- RET
@@ -1,70 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-#include "textflag.h"
5-#include "go_asm.h"
6-
7-// syscall9X calls a function in libc on behalf of the syscall package.
8-// syscall9X takes a pointer to a struct like:
9-// struct {
10-// fn uintptr
11-// a1 uintptr
12-// a2 uintptr
13-// a3 uintptr
14-// a4 uintptr
15-// a5 uintptr
16-// a6 uintptr
17-// a7 uintptr
18-// a8 uintptr
19-// a9 uintptr
20-// r1 uintptr
21-// r2 uintptr
22-// err uintptr
23-// }
24-// syscall9X must be called on the g0 stack with the
25-// C calling convention (use libcCall).
26-GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
27-DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
28-TEXT syscall9X(SB), NOSPLIT, $0
29- PUSHQ BP
30- MOVQ SP, BP
31- SUBQ $32, SP
32- MOVQ DI, 24(BP) // save the pointer
33-
34- MOVQ syscall9Args_f1(DI), X0 // f1
35- MOVQ syscall9Args_f2(DI), X1 // f2
36- MOVQ syscall9Args_f3(DI), X2 // f3
37- MOVQ syscall9Args_f4(DI), X3 // f4
38- MOVQ syscall9Args_f5(DI), X4 // f5
39- MOVQ syscall9Args_f6(DI), X5 // f6
40- MOVQ syscall9Args_f7(DI), X6 // f7
41- MOVQ syscall9Args_f8(DI), X7 // f8
42-
43- MOVQ syscall9Args_fn(DI), R10 // fn
44- MOVQ syscall9Args_a2(DI), SI // a2
45- MOVQ syscall9Args_a3(DI), DX // a3
46- MOVQ syscall9Args_a4(DI), CX // a4
47- MOVQ syscall9Args_a5(DI), R8 // a5
48- MOVQ syscall9Args_a6(DI), R9 // a6
49- MOVQ syscall9Args_a7(DI), R11 // a7
50- MOVQ syscall9Args_a8(DI), R12 // a8
51- MOVQ syscall9Args_a9(DI), R13 // a9
52- MOVQ syscall9Args_a1(DI), DI // a1
53-
54- // push the remaining paramters onto the stack
55- MOVQ R11, 0(SP) // push a7
56- MOVQ R12, 8(SP) // push a8
57- MOVQ R13, 16(SP) // push a9
58- XORL AX, AX // vararg: say "no float args"
59-
60- CALL R10
61-
62- MOVQ 24(BP), DI // get the pointer back
63- MOVQ AX, syscall9Args_r1(DI) // r1
64- MOVQ DX, syscall9Args_r2(DI) // r2
65-
66- XORL AX, AX // no error (it's ignored anyway)
67- ADDQ $32, SP
68- MOVQ BP, SP
69- POPQ BP
70- RET
D sys_linux_arm64.s +0 -71
@@ -1,71 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-#include "textflag.h"
5-#include "go_asm.h"
6-
7-// syscall9X calls a function in libc on behalf of the syscall package.
8-// syscall9X takes a pointer to a struct like:
9-// struct {
10-// fn uintptr
11-// a1 uintptr
12-// a2 uintptr
13-// a3 uintptr
14-// a4 uintptr
15-// a5 uintptr
16-// a6 uintptr
17-// a7 uintptr
18-// a8 uintptr
19-// a9 uintptr
20-// r1 uintptr
21-// r2 uintptr
22-// err uintptr
23-// }
24-// syscall9X must be called on the g0 stack with the
25-// C calling convention (use libcCall).
26-GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
27-DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
28-TEXT syscall9X(SB), NOSPLIT, $0
29- SUB $16, RSP // push structure pointer
30- MOVD R0, 8(RSP)
31-
32- FMOVD syscall9Args_f1(R0), F0 // f1
33- FMOVD syscall9Args_f2(R0), F1 // f2
34- FMOVD syscall9Args_f3(R0), F2 // f3
35- FMOVD syscall9Args_f4(R0), F3 // f4
36- FMOVD syscall9Args_f5(R0), F4 // f5
37- FMOVD syscall9Args_f6(R0), F5 // f6
38- FMOVD syscall9Args_f7(R0), F6 // f7
39- FMOVD syscall9Args_f8(R0), F7 // f8
40-
41- MOVD syscall9Args_fn(R0), R12 // fn
42- MOVD syscall9Args_a2(R0), R1 // a2
43- MOVD syscall9Args_a3(R0), R2 // a3
44- MOVD syscall9Args_a4(R0), R3 // a4
45- MOVD syscall9Args_a5(R0), R4 // a5
46- MOVD syscall9Args_a6(R0), R5 // a6
47- MOVD syscall9Args_a7(R0), R6 // a7
48- MOVD syscall9Args_a8(R0), R7 // a8
49- MOVD syscall9Args_a9(R0), R8 // a9
50- MOVD syscall9Args_a1(R0), R0 // a1
51-
52- // these may be float arguments
53- // so we put them also where C expects floats
54- FMOVD R0, F0 // a1
55- FMOVD R1, F1 // a2
56- FMOVD R2, F2 // a3
57- FMOVD R3, F3 // a4
58- FMOVD R4, F4 // a5
59- FMOVD R5, F5 // a6
60- FMOVD R6, F6 // a7
61- FMOVD R7, F7 // a8
62-
63- MOVD R8, (RSP) // push a9 onto stack
64-
65- BL (R12)
66-
67- MOVD 8(RSP), R2 // pop structure pointer
68- ADD $16, RSP
69- MOVD R0, syscall9Args_r1(R2) // save r1
70- MOVD R1, syscall9Args_r2(R2) // save r2
71- RET
@@ -1,71 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-#include "textflag.h"
5-#include "go_asm.h"
6-
7-// syscall9X calls a function in libc on behalf of the syscall package.
8-// syscall9X takes a pointer to a struct like:
9-// struct {
10-// fn uintptr
11-// a1 uintptr
12-// a2 uintptr
13-// a3 uintptr
14-// a4 uintptr
15-// a5 uintptr
16-// a6 uintptr
17-// a7 uintptr
18-// a8 uintptr
19-// a9 uintptr
20-// r1 uintptr
21-// r2 uintptr
22-// err uintptr
23-// }
24-// syscall9X must be called on the g0 stack with the
25-// C calling convention (use libcCall).
26-GLOBL ·syscall9XABI0(SB), NOPTR|RODATA, $8
27-DATA ·syscall9XABI0(SB)/8, $syscall9X(SB)
28-TEXT syscall9X(SB), NOSPLIT, $0
29- SUB $16, RSP // push structure pointer
30- MOVD R0, 8(RSP)
31-
32- FMOVD syscall9Args_f1(R0), F0 // f1
33- FMOVD syscall9Args_f2(R0), F1 // f2
34- FMOVD syscall9Args_f3(R0), F2 // f3
35- FMOVD syscall9Args_f4(R0), F3 // f4
36- FMOVD syscall9Args_f5(R0), F4 // f5
37- FMOVD syscall9Args_f6(R0), F5 // f6
38- FMOVD syscall9Args_f7(R0), F6 // f7
39- FMOVD syscall9Args_f8(R0), F7 // f8
40-
41- MOVD syscall9Args_fn(R0), R12 // fn
42- MOVD syscall9Args_a2(R0), R1 // a2
43- MOVD syscall9Args_a3(R0), R2 // a3
44- MOVD syscall9Args_a4(R0), R3 // a4
45- MOVD syscall9Args_a5(R0), R4 // a5
46- MOVD syscall9Args_a6(R0), R5 // a6
47- MOVD syscall9Args_a7(R0), R6 // a7
48- MOVD syscall9Args_a8(R0), R7 // a8
49- MOVD syscall9Args_a9(R0), R8 // a9
50- MOVD syscall9Args_a1(R0), R0 // a1
51-
52- // these may be float arguments
53- // so we put them also where C expects floats
54- FMOVD R0, F0 // a1
55- FMOVD R1, F1 // a2
56- FMOVD R2, F2 // a3
57- FMOVD R3, F3 // a4
58- FMOVD R4, F4 // a5
59- FMOVD R5, F5 // a6
60- FMOVD R6, F6 // a7
61- FMOVD R7, F7 // a8
62-
63- MOVD R8, (RSP) // push a9 onto stack
64-
65- BL (R12)
66-
67- MOVD 8(RSP), R2 // pop structure pointer
68- ADD $16, RSP
69- MOVD R0, syscall9Args_r1(R2) // save r1
70- MOVD R1, syscall9Args_r2(R2) // save r2
71- RET
M syscall_cgo_linux.go +3 -2
@@ -6,11 +6,12 @@
66 package purego
77
88 import (
9+ _ "unsafe" // for go:linkname
10+
911 "github.com/ebitengine/purego/internal/cgo"
1012 )
1113
12-// this is linked to a C function from internal/cgo
13-var syscall9XABI0 uintptr
14+var syscall9XABI0 = uintptr(cgo.Syscall9XABI0)
1415
1516 // this is only here to make the assembly files happy :)
1617 type syscall9Args struct {
@@ -6,11 +6,12 @@
6 package purego6 package purego
7 7
8 import (8 import (
9+ _ "unsafe" // for go:linkname
10+
9 "github.com/ebitengine/purego/internal/cgo"11 "github.com/ebitengine/purego/internal/cgo"
10 )12 )
11 13
12-// this is linked to a C function from internal/cgo14+var syscall9XABI0 = uintptr(cgo.Syscall9XABI0)
13-var syscall9XABI0 uintptr
14 15
15 // this is only here to make the assembly files happy :)16 // this is only here to make the assembly files happy :)
16 type syscall9Args struct {17 type syscall9Args struct {
D syscall_nocgo_linux.go +0 -34
@@ -1,34 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-//go:build !cgo && (amd64 || arm64)
5-
6-package purego
7-
8-import (
9- "math"
10- "unsafe"
11-)
12-
13-var syscall9XABI0 uintptr
14-
15-type syscall9Args struct {
16- fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr
17- f1, f2, f3, f4, f5, f6, f7, f8 float64
18- r1, r2, err uintptr
19-}
20-
21-//go:nosplit
22-func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
23- args := syscall9Args{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9,
24- math.Float64frombits(uint64(a1)), math.Float64frombits(uint64(a2)), math.Float64frombits(uint64(a3)),
25- math.Float64frombits(uint64(a4)), math.Float64frombits(uint64(a5)), math.Float64frombits(uint64(a6)),
26- math.Float64frombits(uint64(a7)), math.Float64frombits(uint64(a8)),
27- r1, r2, err}
28- runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args))
29- return args.r1, args.r2, args.err
30-}
31-
32-func NewCallback(_ interface{}) uintptr {
33- panic("purego: NewCallback not supported")
34-}
@@ -1,34 +0,0 @@
1-// SPDX-License-Identifier: Apache-2.0
2-// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3-
4-//go:build !cgo && (amd64 || arm64)
5-
6-package purego
7-
8-import (
9- "math"
10- "unsafe"
11-)
12-
13-var syscall9XABI0 uintptr
14-
15-type syscall9Args struct {
16- fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr
17- f1, f2, f3, f4, f5, f6, f7, f8 float64
18- r1, r2, err uintptr
19-}
20-
21-//go:nosplit
22-func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2, err uintptr) {
23- args := syscall9Args{fn, a1, a2, a3, a4, a5, a6, a7, a8, a9,
24- math.Float64frombits(uint64(a1)), math.Float64frombits(uint64(a2)), math.Float64frombits(uint64(a3)),
25- math.Float64frombits(uint64(a4)), math.Float64frombits(uint64(a5)), math.Float64frombits(uint64(a6)),
26- math.Float64frombits(uint64(a7)), math.Float64frombits(uint64(a8)),
27- r1, r2, err}
28- runtime_cgocall(syscall9XABI0, unsafe.Pointer(&args))
29- return args.r1, args.r2, args.err
30-}
31-
32-func NewCallback(_ interface{}) uintptr {
33- panic("purego: NewCallback not supported")
34-}
R syscall_darwin.go → syscall_sysv.go +7 -0 renamed, 96% similar
@@ -1,6 +1,8 @@
11 // SPDX-License-Identifier: Apache-2.0
22 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
33
4+//go:build darwin || (!cgo && linux && (amd64 || arm64))
5+
46 package purego
57
68 import (
@@ -36,7 +38,12 @@ func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2,
3638 // of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated
3739 // for these callbacks is never released. At least 2000 callbacks can always be created. Although this function
3840 // provides similar functionality to windows.NewCallback it is distinct.
41+//
42+// NOTE: Linux is currently not supported and will panic if called.
3943 func NewCallback(fn interface{}) uintptr {
44+ if runtime.GOOS == "linux" {
45+ panic("purego: NewCallback not supported")
46+ }
4047 return compileCallback(fn)
4148 }
4249
@@ -1,6 +1,8 @@
1 // SPDX-License-Identifier: Apache-2.01 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors2 // SPDX-FileCopyrightText: 2022 The Ebitengine Authors
3 3
4+//go:build darwin || (!cgo && linux && (amd64 || arm64))
5+
4 package purego6 package purego
5 7
6 import (8 import (
@@ -36,7 +38,12 @@ func syscall_syscall9X(fn, a1, a2, a3, a4, a5, a6, a7, a8, a9 uintptr) (r1, r2,
36 // of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated38 // of uintptr. Only a limited number of callbacks may be created in a single Go process, and any memory allocated
37 // for these callbacks is never released. At least 2000 callbacks can always be created. Although this function39 // for these callbacks is never released. At least 2000 callbacks can always be created. Although this function
38 // provides similar functionality to windows.NewCallback it is distinct.40 // provides similar functionality to windows.NewCallback it is distinct.
41+//
42+// NOTE: Linux is currently not supported and will panic if called.
39 func NewCallback(fn interface{}) uintptr {43 func NewCallback(fn interface{}) uintptr {
44+ if runtime.GOOS == "linux" {
45+ panic("purego: NewCallback not supported")
46+ }
40 return compileCallback(fn)47 return compileCallback(fn)
41 }48 }
42 49
R zcallback_darwin_amd64.s → zcallback_amd64.s +2 -0 renamed, 99% similar
@@ -1,5 +1,7 @@
11 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
22
3+//go:build darwin || (!cgo && linux)
4+
35 // runtime·callbackasm is called by external code to
46 // execute Go implemented callback function. It is not
57 // called from the start, instead runtime·compilecallback
@@ -1,5 +1,7 @@
1 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.1 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
2 2
3+//go:build darwin || (!cgo && linux)
4+
3 // runtime·callbackasm is called by external code to5 // runtime·callbackasm is called by external code to
4 // execute Go implemented callback function. It is not6 // execute Go implemented callback function. It is not
5 // called from the start, instead runtime·compilecallback7 // called from the start, instead runtime·compilecallback
R zcallback_darwin_arm64.s → zcallback_arm64.s +2 -0 renamed, 99% similar
@@ -1,5 +1,7 @@
11 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
22
3+//go:build darwin || (!cgo && linux)
4+
35 // External code calls into callbackasm at an offset corresponding
46 // to the callback index. Callbackasm is a table of MOV and B instructions.
57 // The MOV instruction loads R12 with the callback index, and the
@@ -1,5 +1,7 @@
1 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.1 // Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
2 2
3+//go:build darwin || (!cgo && linux)
4+
3 // External code calls into callbackasm at an offset corresponding5 // External code calls into callbackasm at an offset corresponding
4 // to the callback index. Callbackasm is a table of MOV and B instructions.6 // to the callback index. Callbackasm is a table of MOV and B instructions.
5 // The MOV instruction loads R12 with the callback index, and the7 // The MOV instruction loads R12 with the callback index, and the

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