Skip to content

Commit 0788778

Browse files
authored
purego: add wincallback.go (#337)
zcallback_amd64.s and zcallback_arm64.s were generated by wincallback.go in the Go repository. To keep the reproducible repository states, add wincallback.go with some modifications.
1 parent 77ed153 commit 0788778

File tree

5 files changed

+6087
-6002
lines changed

5 files changed

+6087
-6002
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ License that can be found [in the Go Source](https://github.com/golang/go/blob/m
8484
This is a list of the copied files:
8585

8686
* `abi_*.h` from package `runtime/cgo`
87+
* `wincallback.go` from package `runtime`
8788
* `zcallback_darwin_*.s` from package `runtime`
8889
* `internal/fakecgo/abi_*.h` from package `runtime/cgo`
8990
* `internal/fakecgo/asm_GOARCH.s` from package `runtime/cgo`

gen.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
3+
4+
package purego
5+
6+
//go:generate go run wincallback.go

wincallback.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2014 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
//go:build ignore
6+
7+
// Generate Windows callback assembly file.
8+
// This was copied from the Go repository and modified to generate non-Windows assembly files.
9+
10+
package main
11+
12+
import (
13+
"bytes"
14+
"fmt"
15+
"os"
16+
)
17+
18+
const maxCallback = 2000
19+
20+
func genasmAmd64() {
21+
var buf bytes.Buffer
22+
23+
buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
24+
25+
//go:build darwin || freebsd || linux || netbsd
26+
27+
// runtime·callbackasm is called by external code to
28+
// execute Go implemented callback function. It is not
29+
// called from the start, instead runtime·compilecallback
30+
// always returns address into runtime·callbackasm offset
31+
// appropriately so different callbacks start with different
32+
// CALL instruction in runtime·callbackasm. This determines
33+
// which Go callback function is executed later on.
34+
#include "textflag.h"
35+
36+
TEXT callbackasm(SB),NOSPLIT|NOFRAME,$0
37+
`)
38+
for i := 0; i < maxCallback; i++ {
39+
buf.WriteString("\tCALL\tcallbackasm1(SB)\n")
40+
}
41+
if err := os.WriteFile("zcallback_amd64.s", buf.Bytes(), 0644); err != nil {
42+
fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
43+
os.Exit(2)
44+
}
45+
}
46+
47+
func genasmArm64() {
48+
var buf bytes.Buffer
49+
50+
buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
51+
52+
//go:build darwin || freebsd || linux || netbsd
53+
54+
// External code calls into callbackasm at an offset corresponding
55+
// to the callback index. Callbackasm is a table of MOV and B instructions.
56+
// The MOV instruction loads R12 with the callback index, and the
57+
// B instruction branches to callbackasm1.
58+
// callbackasm1 takes the callback index from R12 and
59+
// indexes into an array that stores information about each callback.
60+
// It then calls the Go implementation for that callback.
61+
#include "textflag.h"
62+
63+
TEXT callbackasm(SB),NOSPLIT|NOFRAME,$0
64+
`)
65+
for i := 0; i < maxCallback; i++ {
66+
fmt.Fprintf(&buf, "\tMOVD\t$%d, R12\n", i)
67+
buf.WriteString("\tB\tcallbackasm1(SB)\n")
68+
}
69+
if err := os.WriteFile("zcallback_arm64.s", buf.Bytes(), 0644); err != nil {
70+
fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
71+
os.Exit(2)
72+
}
73+
}
74+
75+
func main() {
76+
genasmAmd64()
77+
genasmArm64()
78+
}

0 commit comments

Comments
 (0)