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