]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile/internal/importer: support final unified IR export format
authorMatthew Dempsky <mdempsky@google.com>
Tue, 1 Mar 2022 04:42:40 +0000 (20:42 -0800)
committerMatthew Dempsky <mdempsky@google.com>
Tue, 29 Mar 2022 00:02:55 +0000 (00:02 +0000)
This updates the cmd/compile/internal/importer to natively support the
"final" unified IR export format. This is really just for unit tests
and symmetry with go/internal/gcimporter though, since
cmd/compile/internal/noder has its own types2.Importer.

Change-Id: I52fbb6134dbc0a903d62c1b04f95d33bd29e0414
Reviewed-on: https://go-review.googlesource.com/c/go/+/388617
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
Reviewed-by: Robert Griesemer <gri@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Trust: Matthew Dempsky <mdempsky@google.com>

src/cmd/compile/internal/importer/exportdata.go
src/cmd/compile/internal/importer/gcimporter.go

index 6a672be9c1bac15a5fa4cc89e69b67c21e95f4f1..42fc5c9a573d04ce302cb7a6d9f71fdd13d86090 100644 (file)
@@ -41,7 +41,9 @@ func readGopackHeader(r *bufio.Reader) (name string, size int, err error) {
 // start of the file before calling this function. The hdr result
 // is the string before the export data, either "$$" or "$$B".
 //
-func FindExportData(r *bufio.Reader) (hdr string, err error) {
+// If size is non-negative, it's the number of bytes of export data
+// still available to read from r.
+func FindExportData(r *bufio.Reader) (hdr string, size int, err error) {
        // Read first line to make sure this is an object file.
        line, err := r.ReadSlice('\n')
        if err != nil {
@@ -52,7 +54,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
        if string(line) == "!<arch>\n" {
                // Archive file. Scan to __.PKGDEF.
                var name string
-               if name, _, err = readGopackHeader(r); err != nil {
+               if name, size, err = readGopackHeader(r); err != nil {
                        return
                }
 
@@ -76,6 +78,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
                err = fmt.Errorf("not a Go object file")
                return
        }
+       size -= len(line)
 
        // Skip over object header to export data.
        // Begins after first line starting with $$.
@@ -84,6 +87,7 @@ func FindExportData(r *bufio.Reader) (hdr string, err error) {
                        err = fmt.Errorf("can't find export data (%v)", err)
                        return
                }
+               size -= len(line)
        }
        hdr = string(line)
 
index ff40be65bbeceebcbb67d3d07c4b87631ea2c904..6c27f8b332fc7e1112566f2c08660ed5819ed991 100644 (file)
@@ -10,6 +10,7 @@ import (
        "cmd/compile/internal/types2"
        "fmt"
        "go/build"
+       "internal/pkgbits"
        "io"
        "io/ioutil"
        "os"
@@ -134,9 +135,9 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
        }
        defer rc.Close()
 
-       var hdr string
        buf := bufio.NewReader(rc)
-       if hdr, err = FindExportData(buf); err != nil {
+       hdr, size, err := FindExportData(buf)
+       if err != nil {
                return
        }
 
@@ -146,17 +147,33 @@ func Import(packages map[string]*types2.Package, path, srcDir string, lookup fun
 
        case "$$B\n":
                var data []byte
-               data, err = ioutil.ReadAll(buf)
+               var r io.Reader = buf
+               if size >= 0 {
+                       r = io.LimitReader(r, int64(size))
+               }
+               data, err = ioutil.ReadAll(r)
                if err != nil {
                        break
                }
 
+               if len(data) == 0 {
+                       err = fmt.Errorf("import %q: missing export data", path)
+                       break
+               }
+               exportFormat := data[0]
+               s := string(data[1:])
+
                // The indexed export format starts with an 'i'; the older
                // binary export format starts with a 'c', 'd', or 'v'
                // (from "version"). Select appropriate importer.
-               if len(data) > 0 && data[0] == 'i' {
-                       pkg, err = ImportData(packages, string(data[1:]), id)
-               } else {
+               switch exportFormat {
+               case 'u':
+                       s = s[:strings.Index(s, "\n$$\n")]
+                       input := pkgbits.NewPkgDecoder(id, s)
+                       pkg = ReadPackage(nil, packages, input)
+               case 'i':
+                       pkg, err = ImportData(packages, s, id)
+               default:
                        err = fmt.Errorf("import %q: old binary export format no longer supported (recompile library)", path)
                }