1
2
3
4
5
6
7
8
9
10 package main
11
12 import (
13 "bytes"
14 "flag"
15 "fmt"
16 "go/ast"
17 "go/format"
18 "go/parser"
19 "go/token"
20 "io"
21 "io/ioutil"
22 "log"
23 "os"
24 "path/filepath"
25 "strings"
26 )
27
28 var stdout = flag.Bool("stdout", false, "write to stdout instead of builtinlist.go")
29
30 func main() {
31 flag.Parse()
32
33 var b bytes.Buffer
34 fmt.Fprintln(&b, "// Code generated by mkbuiltin.go. DO NOT EDIT.")
35 fmt.Fprintln(&b)
36 fmt.Fprintln(&b, "package goobj")
37
38 mkbuiltin(&b)
39
40 out, err := format.Source(b.Bytes())
41 if err != nil {
42 log.Fatal(err)
43 }
44 if *stdout {
45 _, err = os.Stdout.Write(out)
46 } else {
47 err = ioutil.WriteFile("builtinlist.go", out, 0666)
48 }
49 if err != nil {
50 log.Fatal(err)
51 }
52 }
53
54 func mkbuiltin(w io.Writer) {
55 pkg := "runtime"
56 fset := token.NewFileSet()
57 path := filepath.Join("..", "..", "compile", "internal", "typecheck", "builtin", "runtime.go")
58 f, err := parser.ParseFile(fset, path, nil, 0)
59 if err != nil {
60 log.Fatal(err)
61 }
62
63 decls := make(map[string]bool)
64
65 fmt.Fprintf(w, "var builtins = [...]struct{ name string; abi int }{\n")
66 for _, decl := range f.Decls {
67 switch decl := decl.(type) {
68 case *ast.FuncDecl:
69 if decl.Recv != nil {
70 log.Fatal("methods unsupported")
71 }
72 if decl.Body != nil {
73 log.Fatal("unexpected function body")
74 }
75 declName := pkg + "." + decl.Name.Name
76 decls[declName] = true
77 fmt.Fprintf(w, "{%q, 1},\n", declName)
78 case *ast.GenDecl:
79 if decl.Tok == token.IMPORT {
80 continue
81 }
82 if decl.Tok != token.VAR {
83 log.Fatal("unhandled declaration kind", decl.Tok)
84 }
85 for _, spec := range decl.Specs {
86 spec := spec.(*ast.ValueSpec)
87 if len(spec.Values) != 0 {
88 log.Fatal("unexpected values")
89 }
90 for _, name := range spec.Names {
91 declName := pkg + "." + name.Name
92 decls[declName] = true
93 fmt.Fprintf(w, "{%q, 0},\n", declName)
94 }
95 }
96 default:
97 log.Fatal("unhandled decl type", decl)
98 }
99 }
100
101
102
103
104
105 extras := append(fextras[:], enumerateBasicTypes()...)
106 for _, b := range extras {
107 prefix := ""
108 if !strings.HasPrefix(b.name, "type.") {
109 prefix = pkg + "."
110 }
111 name := prefix + b.name
112 if decls[name] {
113 log.Fatalf("%q already added -- mkbuiltin.go out of sync?", name)
114 }
115 fmt.Fprintf(w, "{%q, %d},\n", name, b.abi)
116 }
117 fmt.Fprintln(w, "}")
118 }
119
120
121
122
123
124 func enumerateBasicTypes() []extra {
125 names := [...]string{
126 "int8", "uint8", "int16", "uint16",
127 "int32", "uint32", "int64", "uint64",
128 "float32", "float64", "complex64", "complex128",
129 "unsafe.Pointer", "uintptr", "bool", "string", "error",
130 "func(error) string"}
131 result := []extra{}
132 for _, n := range names {
133 result = append(result, extra{"type." + n, 0})
134 result = append(result, extra{"type.*" + n, 0})
135 }
136 return result
137 }
138
139 type extra struct {
140 name string
141 abi int
142 }
143
144 var fextras = [...]extra{
145
146 {"deferproc", 1},
147 {"deferprocStack", 1},
148 {"deferreturn", 1},
149 {"newproc", 1},
150 {"panicoverflow", 1},
151 {"sigpanic", 1},
152
153
154 {"gcWriteBarrier", 1},
155 {"duffzero", 1},
156 {"duffcopy", 1},
157
158
159 {"morestack", 0},
160 {"morestackc", 0},
161 {"morestack_noctxt", 0},
162 }
163
View as plain text