go/src/cmd/compile/internal/gc/mkbuiltin.go
Matthew Dempsky 3f2cb493e5 cmd/compile: handle unsafe builtins like universal builtins
Reuse the same mechanisms for handling universal builtins like len to
handle unsafe.Sizeof, etc. Allows us to drop package unsafe's export
data, and simplifies some code.

Updates #17508.

Change-Id: I620e0617c24e57e8a2d7cccd0e2de34608779656
Reviewed-on: https://go-review.googlesource.com/31433
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
2016-10-18 22:34:44 +00:00

93 lines
2 KiB
Go

// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build ignore
// Generate builtin.go from builtin/runtime.go.
// Run this after changing builtin/runtime.go
// or after changing the export metadata format in the compiler.
// Either way, you need to have a working compiler binary first.
// See bexport.go for how to make an export metadata format change.
package main
import (
"bytes"
"flag"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
)
var stdout = flag.Bool("stdout", false, "write to stdout instead of builtin.go")
func main() {
flag.Parse()
var b bytes.Buffer
fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
fmt.Fprintln(&b, "")
fmt.Fprintln(&b, "package gc")
mkbuiltin(&b, "runtime")
var err error
if *stdout {
_, err = os.Stdout.Write(b.Bytes())
} else {
err = ioutil.WriteFile("builtin.go", b.Bytes(), 0666)
}
if err != nil {
log.Fatal(err)
}
}
// Compile .go file, import data from .o file, and write Go string version.
func mkbuiltin(w io.Writer, name string) {
args := []string{"tool", "compile", "-A"}
if name == "runtime" {
args = append(args, "-u")
}
args = append(args, "builtin/"+name+".go")
if err := exec.Command("go", args...).Run(); err != nil {
log.Fatal(err)
}
obj := name + ".o"
defer os.Remove(obj)
b, err := ioutil.ReadFile(obj)
if err != nil {
log.Fatal(err)
}
// Look for $$B that introduces binary export data.
i := bytes.Index(b, []byte("\n$$B\n"))
if i < 0 {
log.Fatal("did not find beginning of export data")
}
b = b[i+5:]
// Look for $$ that closes export data.
i = bytes.Index(b, []byte("\n$$\n"))
if i < 0 {
log.Fatal("did not find end of export data")
}
b = b[:i+4]
// Process and reformat export data.
const n = 40 // number of bytes per line
fmt.Fprintf(w, "\nconst %simport = \"\"", name)
for len(b) > 0 {
i := len(b)
if i > n {
i = n
}
fmt.Fprintf(w, " +\n\t%q", b[:i])
b = b[i:]
}
fmt.Fprintf(w, "\n")
}