github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/goobj2/mkbuiltin.go (about) 1 // Copyright 2019 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 builtinlist.go from cmd/compile/internal/gc/builtin/runtime.go. 8 9 package main 10 11 import ( 12 "bytes" 13 "flag" 14 "fmt" 15 "go/ast" 16 "go/format" 17 "go/parser" 18 "go/token" 19 "io" 20 "io/ioutil" 21 "log" 22 "os" 23 "path/filepath" 24 ) 25 26 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtinlist.go") 27 28 func main() { 29 flag.Parse() 30 31 var b bytes.Buffer 32 fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.") 33 fmt.Fprintln(&b) 34 fmt.Fprintln(&b, "package goobj2") 35 36 mkbuiltin(&b) 37 38 out, err := format.Source(b.Bytes()) 39 if err != nil { 40 log.Fatal(err) 41 } 42 if *stdout { 43 _, err = os.Stdout.Write(out) 44 } else { 45 err = ioutil.WriteFile("builtinlist.go", out, 0666) 46 } 47 if err != nil { 48 log.Fatal(err) 49 } 50 } 51 52 func mkbuiltin(w io.Writer) { 53 pkg := "runtime" 54 fset := token.NewFileSet() 55 path := filepath.Join("..", "..", "compile", "internal", "gc", "builtin", "runtime.go") 56 f, err := parser.ParseFile(fset, path, nil, 0) 57 if err != nil { 58 log.Fatal(err) 59 } 60 61 decls := make(map[string]bool) 62 63 fmt.Fprintf(w, "var builtins = [...]struct{ name string; abi int }{\n") 64 for _, decl := range f.Decls { 65 switch decl := decl.(type) { 66 case *ast.FuncDecl: 67 if decl.Recv != nil { 68 log.Fatal("methods unsupported") 69 } 70 if decl.Body != nil { 71 log.Fatal("unexpected function body") 72 } 73 declName := pkg + "." + decl.Name.Name 74 decls[declName] = true 75 fmt.Fprintf(w, "{%q, 1},\n", declName) // functions are ABIInternal (1) 76 case *ast.GenDecl: 77 if decl.Tok == token.IMPORT { 78 continue 79 } 80 if decl.Tok != token.VAR { 81 log.Fatal("unhandled declaration kind", decl.Tok) 82 } 83 for _, spec := range decl.Specs { 84 spec := spec.(*ast.ValueSpec) 85 if len(spec.Values) != 0 { 86 log.Fatal("unexpected values") 87 } 88 for _, name := range spec.Names { 89 declName := pkg + "." + name.Name 90 decls[declName] = true 91 fmt.Fprintf(w, "{%q, 0},\n", declName) // variables are ABI0 92 } 93 } 94 default: 95 log.Fatal("unhandled decl type", decl) 96 } 97 } 98 99 // The list above only contains ones that are used by the frontend. 100 // The backend may create more references of builtin functions. 101 // Add them. 102 for _, b := range extra { 103 name := pkg + "." + b.name 104 if decls[name] { 105 log.Fatalf("%q already added -- mkbuiltin.go out of sync?", name) 106 } 107 fmt.Fprintf(w, "{%q, %d},\n", name, b.abi) 108 } 109 fmt.Fprintln(w, "}") 110 } 111 112 var extra = [...]struct { 113 name string 114 abi int 115 }{ 116 {"gcWriteBarrier", 0}, // asm function, ABI0 117 {"deferproc", 1}, 118 {"deferprocStack", 1}, 119 {"deferreturn", 1}, 120 {"newproc", 1}, 121 {"morestack", 0}, // asm function, ABI0 122 {"morestackc", 0}, // asm function, ABI0 123 {"morestack_noctxt", 0}, // asm function, ABI0 124 }