1
2
3
4
5
6
7
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 "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)
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)
92 }
93 }
94 default:
95 log.Fatal("unhandled decl type", decl)
96 }
97 }
98
99
100
101
102
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
119
120
121
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
144 {"deferproc", 1},
145 {"deferprocStack", 1},
146 {"deferreturn", 1},
147 {"newproc", 1},
148 {"panicoverflow", 1},
149 {"sigpanic", 1},
150
151
152 {"gcWriteBarrier", 1},
153 {"duffzero", 1},
154 {"duffcopy", 1},
155
156
157 {"morestack", 0},
158 {"morestackc", 0},
159 {"morestack_noctxt", 0},
160 }
161
View as plain text