github.com/Rookout/GoSDK@v0.1.48/pkg/services/assembler/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.assembler file.
     4  
     5  //go:build ignore
     6  // +build ignore
     7  
     8  // Generate builtinlist.go from cmd/compile/internal/typecheck/builtin/runtime.go.
     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  	"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 = os.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", "typecheck", "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", 1},
   154  	{"duffzero", 1},
   155  	{"duffcopy", 1},
   156  
   157  	
   158  	{"morestack", 0},        
   159  	{"morestackc", 0},       
   160  	{"morestack_noctxt", 0}, 
   161  }