Source file
src/runtime/wincallback.go
1
2
3
4
5
6
7
8
9 package main
10
11 import (
12 "bytes"
13 "fmt"
14 "os"
15 )
16
17 const maxCallback = 2000
18
19 func genasm386Amd64() {
20 var buf bytes.Buffer
21
22 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
23
24 //go:build 386 || amd64
25
26 #include "textflag.h"
27
28 // runtime·callbackasm is called by external code to
29 // execute Go implemented callback function. It is not
30 // called from the start, instead runtime·compilecallback
31 // always returns address into runtime·callbackasm offset
32 // appropriately so different callbacks start with different
33 // CALL instruction in runtime·callbackasm. This determines
34 // which Go callback function is executed later on.
35
36 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
37 `)
38 for i := 0; i < maxCallback; i++ {
39 buf.WriteString("\tCALL\truntime·callbackasm1(SB)\n")
40 }
41
42 filename := fmt.Sprintf("zcallback_windows.s")
43 err := os.WriteFile(filename, buf.Bytes(), 0666)
44 if err != nil {
45 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
46 os.Exit(2)
47 }
48 }
49
50 func genasmArm() {
51 var buf bytes.Buffer
52
53 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
54
55 // External code calls into callbackasm at an offset corresponding
56 // 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
58 // B instruction branches to callbackasm1.
59 // callbackasm1 takes the callback index from R12 and
60 // indexes into an array that stores information about each callback.
61 // It then calls the Go implementation for that callback.
62 #include "textflag.h"
63
64 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
65 `)
66 for i := 0; i < maxCallback; i++ {
67 fmt.Fprintf(&buf, "\tMOVW\t$%d, R12\n", i)
68 buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
69 }
70
71 err := os.WriteFile("zcallback_windows_arm.s", buf.Bytes(), 0666)
72 if err != nil {
73 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
74 os.Exit(2)
75 }
76 }
77
78 func genasmArm64() {
79 var buf bytes.Buffer
80
81 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
82
83 // External code calls into callbackasm at an offset corresponding
84 // to the callback index. Callbackasm is a table of MOV and B instructions.
85 // The MOV instruction loads R12 with the callback index, and the
86 // B instruction branches to callbackasm1.
87 // callbackasm1 takes the callback index from R12 and
88 // indexes into an array that stores information about each callback.
89 // It then calls the Go implementation for that callback.
90 #include "textflag.h"
91
92 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0
93 `)
94 for i := 0; i < maxCallback; i++ {
95 fmt.Fprintf(&buf, "\tMOVD\t$%d, R12\n", i)
96 buf.WriteString("\tB\truntime·callbackasm1(SB)\n")
97 }
98
99 err := os.WriteFile("zcallback_windows_arm64.s", buf.Bytes(), 0666)
100 if err != nil {
101 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
102 os.Exit(2)
103 }
104 }
105
106 func gengo() {
107 var buf bytes.Buffer
108
109 fmt.Fprintf(&buf, `// Code generated by wincallback.go using 'go generate'. DO NOT EDIT.
110
111 package runtime
112
113 const cb_max = %d // maximum number of windows callbacks allowed
114 `, maxCallback)
115 err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666)
116 if err != nil {
117 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err)
118 os.Exit(2)
119 }
120 }
121
122 func main() {
123 genasm386Amd64()
124 genasmArm()
125 genasmArm64()
126 gengo()
127 }
128
View as plain text