detached 46cb710

purego: make callbacks with more than 6 arguments work properly on amd64 (#33)

commit
46cb7109989cf10d15372fb94e8c608b34e17b49
author
TotallyGamerJet · · 2022-09-06 11:03 UTC
committer
GitHub · · 2022-09-06 11:03 UTC
parent
aeed57c
signature
GPG Unverified4AEE18F83AFDEB23 The key is unknown
3 files · +20 -13
M objc/objc_runtime_darwin_test.go +4 -4
@@ -43,13 +43,13 @@ func ExampleClass_AddIvar() {
4343 }
4444
4545 func ExampleIMP() {
46- imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL) {
47- fmt.Println("IMP:", self, _cmd)
46+ imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL, a3, a4, a5, a6, a7, a8, a9 int) {
47+ fmt.Println("IMP:", self, _cmd, a3, a4, a5, a6, a7, a8, a9)
4848 })
4949
50- purego.SyscallN(uintptr(imp), 105, 567)
50+ purego.SyscallN(uintptr(imp), 105, 567, 9, 2, 3, ^uintptr(4), 4, 8, 9)
5151
52- // Output: IMP: 105 567
52+ // Output: IMP: 105 567 9 2 3 -5 4 8 9
5353 }
5454
5555 func ExampleID_SendSuper() {
@@ -43,13 +43,13 @@ func ExampleClass_AddIvar() {
43 }43 }
44 44
45 func ExampleIMP() {45 func ExampleIMP() {
46- imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL) {46+ imp := objc.NewIMP(func(self objc.ID, _cmd objc.SEL, a3, a4, a5, a6, a7, a8, a9 int) {
47- fmt.Println("IMP:", self, _cmd)47+ fmt.Println("IMP:", self, _cmd, a3, a4, a5, a6, a7, a8, a9)
48 })48 })
49 49
50- purego.SyscallN(uintptr(imp), 105, 567)50+ purego.SyscallN(uintptr(imp), 105, 567, 9, 2, 3, ^uintptr(4), 4, 8, 9)
51 51
52- // Output: IMP: 105 56752+ // Output: IMP: 105 567 9 2 3 -5 4 8 9
53 }53 }
54 54
55 func ExampleID_SendSuper() {55 func ExampleID_SendSuper() {
M sys_darwin_amd64.s +15 -8
@@ -88,16 +88,19 @@ TEXT callbackasm1(SB), NOSPLIT, $0
8888 MOVQ 0(SP), AX
8989 ADDQ $8, SP
9090
91+ MOVQ 0(SP), R12 // get the return SP so that we can align register args with stack args
92+
9193 // make space for first six arguments below the frame
92- // TODO: check to make sure that arguments 7 and above are right after these six
9394 ADJSP $6*8, SP
94- MOVQ DI, 0(SP)
95- MOVQ SI, 8(SP)
96- MOVQ DX, 16(SP)
97- MOVQ CX, 24(SP)
98- MOVQ R8, 32(SP)
99- MOVQ R9, 40(SP)
100- LEAQ (SP), R8 // R8 = address of args vector
95+ MOVQ DI, 8(SP)
96+ MOVQ SI, 16(SP)
97+ MOVQ DX, 24(SP)
98+ MOVQ CX, 32(SP)
99+ MOVQ R8, 40(SP)
100+ MOVQ R9, 48(SP)
101+ LEAQ 8(SP), R8 // R8 = address of args vector
102+
103+ MOVQ R12, 0(SP) // push the stack pointer below registers
101104
102105 // determine index into runtime·cbs table
103106 MOVQ $callbackasm(SB), DX
@@ -132,6 +135,10 @@ TEXT callbackasm1(SB), NOSPLIT, $0
132135
133136 POP_REGS_HOST_TO_ABI0()
134137
138+ MOVQ 0(SP), R12 // get the SP back
139+
135140 ADJSP $-6*8, SP // remove arguments
136141
142+ MOVQ R12, 0(SP)
143+
137144 RET
@@ -88,16 +88,19 @@ TEXT callbackasm1(SB), NOSPLIT, $0
88 MOVQ 0(SP), AX88 MOVQ 0(SP), AX
89 ADDQ $8, SP89 ADDQ $8, SP
90 90
91+ MOVQ 0(SP), R12 // get the return SP so that we can align register args with stack args
92+
91 // make space for first six arguments below the frame93 // make space for first six arguments below the frame
92- // TODO: check to make sure that arguments 7 and above are right after these six
93 ADJSP $6*8, SP94 ADJSP $6*8, SP
94- MOVQ DI, 0(SP)95+ MOVQ DI, 8(SP)
95- MOVQ SI, 8(SP)96+ MOVQ SI, 16(SP)
96- MOVQ DX, 16(SP)97+ MOVQ DX, 24(SP)
97- MOVQ CX, 24(SP)98+ MOVQ CX, 32(SP)
98- MOVQ R8, 32(SP)99+ MOVQ R8, 40(SP)
99- MOVQ R9, 40(SP)100+ MOVQ R9, 48(SP)
100- LEAQ (SP), R8 // R8 = address of args vector101+ LEAQ 8(SP), R8 // R8 = address of args vector
102+
103+ MOVQ R12, 0(SP) // push the stack pointer below registers
101 104
102 // determine index into runtime·cbs table105 // determine index into runtime·cbs table
103 MOVQ $callbackasm(SB), DX106 MOVQ $callbackasm(SB), DX
@@ -132,6 +135,10 @@ TEXT callbackasm1(SB), NOSPLIT, $0
132 135
133 POP_REGS_HOST_TO_ABI0()136 POP_REGS_HOST_TO_ABI0()
134 137
138+ MOVQ 0(SP), R12 // get the SP back
139+
135 ADJSP $-6*8, SP // remove arguments140 ADJSP $-6*8, SP // remove arguments
136 141
142+ MOVQ R12, 0(SP)
143+
137 RET144 RET
M sys_darwin_arm64.s +1 -1
@@ -77,7 +77,7 @@ TEXT callbackWrapInternal<>(SB), NOSPLIT, $0-0
7777 TEXT callbackasm1(SB), NOSPLIT, $208-0
7878 NO_LOCAL_POINTERS
7979
80- // On entry, the trampoline in zcallback_windows_arm64.s left
80+ // On entry, the trampoline in zcallback_darwin_arm64.s left
8181 // the callback index in R12 (which is volatile in the C ABI).
8282
8383 // Save callback register arguments R0-R7.
@@ -77,7 +77,7 @@ TEXT callbackWrapInternal<>(SB), NOSPLIT, $0-0
77 TEXT callbackasm1(SB), NOSPLIT, $208-077 TEXT callbackasm1(SB), NOSPLIT, $208-0
78 NO_LOCAL_POINTERS78 NO_LOCAL_POINTERS
79 79
80- // On entry, the trampoline in zcallback_windows_arm64.s left80+ // On entry, the trampoline in zcallback_darwin_arm64.s left
81 // the callback index in R12 (which is volatile in the C ABI).81 // the callback index in R12 (which is volatile in the C ABI).
82 82
83 // Save callback register arguments R0-R7.83 // Save callback register arguments R0-R7.

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