Commit 7555f7f2 authored by Matthew Dempsky's avatar Matthew Dempsky

cmd/compile: cleanup mkbuiltin.go

Changes largely in preparation for eventually switching the builtin
export data to use the new binary format.

Replace fancy incremental line-by-line scanning with simply reading
the entire object file into memory, finding the export data section,
and processing it that way.

Just use "package runtime" and "package unsafe" in the builtin Go
source files so we don't need to rewrite references to "PACKAGE".

Stop looking for init_PACKAGE_function; it doesn't exist anyway.

Compile package runtime with -u so that its export data marks it as a
"safe" package.

Eliminate requirement to pass "runtime" and "unsafe" as command-line
arguments so that just "go run mkbuiltin.go" works.

Only rewrite builtin.go when successful.

Change-Id: I4addfde9e0cfb30607c7a83de686bde0ad1f035a
Reviewed-on: https://go-review.googlesource.com/19624Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent 7d80291c
......@@ -3,7 +3,7 @@
package gc
const runtimeimport = "" +
"package runtime\n" +
"package runtime safe\n" +
"func @\"\".newobject (@\"\".typ·2 *byte) (? *any)\n" +
"func @\"\".panicindex ()\n" +
"func @\"\".panicslice ()\n" +
......
......@@ -8,7 +8,7 @@
// +build ignore
package PACKAGE
package runtime
// emitted by compiler, not referred to by go programs
......
......@@ -8,7 +8,7 @@
// +build ignore
package PACKAGE
package unsafe
type Pointer uintptr // not really; filled in by compiler
......
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:generate go run mkbuiltin.go runtime unsafe
//go:generate go run mkbuiltin.go
package gc
......
......@@ -4,95 +4,79 @@
// +build ignore
// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go
// (passed as arguments on the command line by a go:generate comment).
// Generate builtin.go from builtin/runtime.go and builtin/unsafe.go.
// Run this after changing builtin/runtime.go and builtin/unsafe.go
// or after changing the export metadata format in the compiler.
// Either way, you need to have a working compiler binary first.
package main
import (
"bufio"
"bytes"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)
func main() {
f, err := os.Create("builtin.go")
if err != nil {
log.Fatal(err)
}
defer f.Close()
w := bufio.NewWriter(f)
var b bytes.Buffer
fmt.Fprintln(&b, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
fmt.Fprintln(&b, "")
fmt.Fprintln(&b, "package gc")
fmt.Fprintln(w, "// AUTO-GENERATED by mkbuiltin.go; DO NOT EDIT")
fmt.Fprintln(w, "")
fmt.Fprintln(w, "package gc")
for _, name := range os.Args[1:] {
mkbuiltin(w, name)
}
mkbuiltin(&b, "runtime")
mkbuiltin(&b, "unsafe")
if err := w.Flush(); err != nil {
if err := ioutil.WriteFile("builtin.go", b.Bytes(), 0666); err != nil {
log.Fatal(err)
}
}
// Compile .go file, import data from .6 file, and write Go string version.
// Compile .go file, import data from .o file, and write Go string version.
func mkbuiltin(w io.Writer, name string) {
if err := exec.Command("go", "tool", "compile", "-A", "builtin/"+name+".go").Run(); err != nil {
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)
r, err := os.Open(obj)
b, err := ioutil.ReadFile(obj)
if err != nil {
log.Fatal(err)
}
defer r.Close()
scanner := bufio.NewScanner(r)
// Look for $$ that introduces imports.
for scanner.Scan() {
if strings.Contains(scanner.Text(), "$$") {
goto Begin
}
}
i := bytes.Index(b, []byte("\n$$\n"))
if i < 0 {
log.Fatal("did not find beginning of imports")
}
i += 4
Begin:
initfunc := fmt.Sprintf("init_%s_function", name)
fmt.Fprintf(w, "\nconst %simport = \"\" +\n", name)
// sys.go claims to be in package PACKAGE to avoid
// conflicts during "go tool compile sys.go". Rename PACKAGE to $2.
replacer := strings.NewReplacer("PACKAGE", name)
// Process imports, stopping at $$ that closes them.
for scanner.Scan() {
p := scanner.Text()
if strings.Contains(p, "$$") {
goto End
// Look for $$ that closes imports.
j := bytes.Index(b[i:], []byte("\n$$\n"))
if j < 0 {
log.Fatal("did not find end of imports")
}
j += i + 4
// Process and reformat imports.
fmt.Fprintf(w, "\nconst %simport = \"\"", name)
for _, p := range bytes.SplitAfter(b[i:j], []byte("\n")) {
// Chop leading white space.
p = strings.TrimLeft(p, " \t")
// Cut out decl of init_$1_function - it doesn't exist.
if strings.Contains(p, initfunc) {
p = bytes.TrimLeft(p, " \t")
if len(p) == 0 {
continue
}
fmt.Fprintf(w, "\t%q +\n", replacer.Replace(p)+"\n")
fmt.Fprintf(w, " +\n\t%q", p)
}
log.Fatal("did not find end of imports")
End:
fmt.Fprintf(w, "\t\"$$\\n\"\n")
fmt.Fprintf(w, "\n")
}
......@@ -67,7 +67,7 @@ func (p *parser) loadsys() {
importpkg = Runtimepkg
if Debug['A'] != 0 {
cannedimports("runtime.Builtin", "package runtime\n\n$$\n\n")
cannedimports("runtime.Builtin", "package runtime safe\n\n$$\n\n")
} else {
cannedimports("runtime.Builtin", runtimeimport)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment