github.com/bir3/gocompiler@v0.9.2202/src/cmd/internal/goobj/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 //go:build ignore 6 7 // Generate builtinlist.go from cmd/compile/internal/typecheck/builtin/runtime.go. 8 9 package main 10 11 import ( 12 "bytes" 13 "flag" 14 "fmt" 15 "github.com/bir3/gocompiler/src/go/ast" 16 "github.com/bir3/gocompiler/src/go/format" 17 "github.com/bir3/gocompiler/src/go/parser" 18 "github.com/bir3/gocompiler/src/go/token" 19 "io" 20 "log" 21 "os" 22 "path/filepath" 23 "strings" 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 goobj") 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 = os.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", "typecheck", "_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 // We also want to include predefined types. 102 // Add them. 103 extras := append(fextras[:], enumerateBasicTypes()...) 104 for _, b := range extras { 105 prefix := "" 106 if !strings.HasPrefix(b.name, "type:") { 107 prefix = pkg + "." 108 } 109 name := prefix + b.name 110 if decls[name] { 111 log.Fatalf("%q already added -- mkbuiltin.go out of sync?", name) 112 } 113 fmt.Fprintf(w, "{%q, %d},\n", name, b.abi) 114 } 115 fmt.Fprintln(w, "}") 116 } 117 118 // enumerateBasicTypes returns the symbol names for basic types that are 119 // defined in the runtime and referenced in other packages. 120 // Needs to be kept in sync with reflect.go:WriteBasicTypes() and 121 // reflect.go:writeType() in the compiler. 122 func enumerateBasicTypes() []extra { 123 names := [...]string{ 124 "int8", "uint8", "int16", "uint16", 125 "int32", "uint32", "int64", "uint64", 126 "float32", "float64", "complex64", "complex128", 127 "unsafe.Pointer", "uintptr", "bool", "string", "error", 128 "func(error) string"} 129 result := []extra{} 130 for _, n := range names { 131 result = append(result, extra{"type:" + n, 0}) 132 result = append(result, extra{"type:*" + n, 0}) 133 } 134 return result 135 } 136 137 type extra struct { 138 name string 139 abi int 140 } 141 142 var fextras = [...]extra{ 143 // compiler frontend inserted calls (sysfunc) 144 {"deferproc", 1}, 145 {"deferprocStack", 1}, 146 {"deferreturn", 1}, 147 {"newproc", 1}, 148 {"panicoverflow", 1}, 149 {"sigpanic", 1}, 150 151 // compiler backend inserted calls 152 {"gcWriteBarrier", 1}, 153 {"duffzero", 1}, 154 {"duffcopy", 1}, 155 156 // assembler backend inserted calls 157 {"morestack", 0}, // asm function, ABI0 158 {"morestackc", 0}, // asm function, ABI0 159 {"morestack_noctxt", 0}, // asm function, ABI0 160 }