github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/runtime/wincallback.go (about) 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 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 }