github.com/geraldss/go/src@v0.0.0-20210511222824-ac7d0ebfc235/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 // +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 // +build 386 amd64 25 // runtime·callbackasm is called by external code to 26 // execute Go implemented callback function. It is not 27 // called from the start, instead runtime·compilecallback 28 // always returns address into runtime·callbackasm offset 29 // appropriately so different callbacks start with different 30 // CALL instruction in runtime·callbackasm. This determines 31 // which Go callback function is executed later on. 32 33 TEXT runtime·callbackasm(SB),7,$0 34 `) 35 for i := 0; i < maxCallback; i++ { 36 buf.WriteString("\tCALL\truntime·callbackasm1(SB)\n") 37 } 38 39 filename := fmt.Sprintf("zcallback_windows.s") 40 err := os.WriteFile(filename, buf.Bytes(), 0666) 41 if err != nil { 42 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 43 os.Exit(2) 44 } 45 } 46 47 func genasmArm() { 48 var buf bytes.Buffer 49 50 buf.WriteString(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 51 52 // External code calls into callbackasm at an offset corresponding 53 // to the callback index. Callbackasm is a table of MOV and B instructions. 54 // The MOV instruction loads R12 with the callback index, and the 55 // B instruction branches to callbackasm1. 56 // callbackasm1 takes the callback index from R12 and 57 // indexes into an array that stores information about each callback. 58 // It then calls the Go implementation for that callback. 59 #include "textflag.h" 60 61 TEXT runtime·callbackasm(SB),NOSPLIT|NOFRAME,$0 62 `) 63 for i := 0; i < maxCallback; i++ { 64 buf.WriteString(fmt.Sprintf("\tMOVW\t$%d, R12\n", i)) 65 buf.WriteString("\tB\truntime·callbackasm1(SB)\n") 66 } 67 68 err := os.WriteFile("zcallback_windows_arm.s", buf.Bytes(), 0666) 69 if err != nil { 70 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 71 os.Exit(2) 72 } 73 } 74 75 func gengo() { 76 var buf bytes.Buffer 77 78 buf.WriteString(fmt.Sprintf(`// Code generated by wincallback.go using 'go generate'. DO NOT EDIT. 79 80 package runtime 81 82 const cb_max = %d // maximum number of windows callbacks allowed 83 `, maxCallback)) 84 err := os.WriteFile("zcallback_windows.go", buf.Bytes(), 0666) 85 if err != nil { 86 fmt.Fprintf(os.Stderr, "wincallback: %s\n", err) 87 os.Exit(2) 88 } 89 } 90 91 func main() { 92 genasm386Amd64() 93 genasmArm() 94 gengo() 95 }