Skip to content

Commit

Permalink
internal/gcimporter: synchronize with internal/exportdata
Browse files Browse the repository at this point in the history
Use the copies of the functions from internal/exportdata.

The implementations are now quite uniform between
exportdata.go in GOROOT/src/internal/exportdata and internal/gcimporter
as well as gcimporter.go in GOROOT/src/go/internal/gcimporter and
internal/gcimporter.

Fixes golang/go#70651

Change-Id: I8c2a55ca8c09d504315b9ccd7c676a5c2023ca68
Reviewed-on: https://go-review.googlesource.com/c/tools/+/633660
Commit-Queue: Tim King <[email protected]>
LUCI-TryBot-Result: Go LUCI <[email protected]>
Reviewed-by: Robert Griesemer <[email protected]>
Reviewed-by: Robert Findley <[email protected]>
  • Loading branch information
timothy-king authored and Go LUCI committed Dec 12, 2024
1 parent c1ff179 commit c803483
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 71 deletions.
49 changes: 12 additions & 37 deletions internal/gcimporter/exportdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,58 +31,33 @@ import (
// accept inputs produced by the last two releases of cmd/compile,
// plus tip.
func FindExportData(r *bufio.Reader) (size int64, err error) {
// Read first line to make sure this is an object file.
line, err := r.ReadSlice('\n')
arsize, err := FindPackageDefinition(r)
if err != nil {
err = fmt.Errorf("can't find export data (%v)", err)
return
}

// Is the first line an archive file signature?
if string(line) != "!<arch>\n" {
err = fmt.Errorf("not the start of an archive file (%q)", line)
return
}

// Archive file with the first file being __.PKGDEF.
arsize := readArchiveHeader(r, "__.PKGDEF")
if arsize <= 0 {
err = fmt.Errorf("not a package file")
return
}
size = int64(arsize)

// Read first line of __.PKGDEF data, so that line
// is once again the first line of the input.
if line, err = r.ReadSlice('\n'); err != nil {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
size -= int64(len(line))

// Now at __.PKGDEF in archive or still at beginning of file.
// Either way, line should begin with "go object ".
if !strings.HasPrefix(string(line), "go object ") {
err = fmt.Errorf("not a Go object file")
objapi, headers, err := ReadObjectHeaders(r)
if err != nil {
return
}

// Skip over object headers to get to the export data section header "$$B\n".
// Object headers are lines that do not start with '$'.
for line[0] != '$' {
if line, err = r.ReadSlice('\n'); err != nil {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
size -= int64(len(line))
size -= int64(len(objapi))
for _, h := range headers {
size -= int64(len(h))
}

// Check for the binary export data section header "$$B\n".
// TODO(taking): Unify with ReadExportDataHeader so that it stops at the 'u' instead of reading
line, err := r.ReadSlice('\n')
if err != nil {
return
}
hdr := string(line)
if hdr != "$$B\n" {
err = fmt.Errorf("unknown export data header: %q", hdr)
return
}
size -= int64(len(hdr))

// For files with a binary export data header "$$B\n",
// these are always terminated by an end-of-section marker "\n$$\n".
Expand Down
41 changes: 7 additions & 34 deletions internal/gcimporter/gcimporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const (
// Import is only used in tests.
func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDir string, lookup func(path string) (io.ReadCloser, error)) (pkg *types.Package, err error) {
var rc io.ReadCloser
var filename, id string
var id string
if lookup != nil {
// With custom lookup specified, assume that caller has
// converted path to a canonical import path for use in the map.
Expand All @@ -65,6 +65,7 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi
}
rc = f
} else {
var filename string
filename, id, err = FindPkg(path, srcDir)
if filename == "" {
if path == "unsafe" {
Expand Down Expand Up @@ -93,43 +94,15 @@ func Import(fset *token.FileSet, packages map[string]*types.Package, path, srcDi
}
defer rc.Close()

var size int64
buf := bufio.NewReader(rc)
if size, err = FindExportData(buf); err != nil {
return
}

var data []byte
data, err = io.ReadAll(buf)
data, err := ReadUnified(buf)
if err != nil {
err = fmt.Errorf("import %q: %v", path, err)
return
}
if len(data) == 0 {
return nil, fmt.Errorf("no data to load a package from for path %s", id)
}

// Select appropriate importer.
switch data[0] {
case 'v', 'c', 'd':
// binary: emitted by cmd/compile till go1.10; obsolete.
return nil, fmt.Errorf("binary (%c) import format is no longer supported", data[0])
// unified: emitted by cmd/compile since go1.20.
_, pkg, err = UImportData(fset, packages, data, id)

case 'i':
// indexed: emitted by cmd/compile till go1.19;
// now used only for serializing go/types.
// See https://github.com/golang/go/issues/69491.
return nil, fmt.Errorf("indexed (i) import format is no longer supported")

case 'u':
// unified: emitted by cmd/compile since go1.20.
_, pkg, err := UImportData(fset, packages, data[1:size], id)
return pkg, err

default:
l := len(data)
if l > 10 {
l = 10
}
return nil, fmt.Errorf("unexpected export data with prefix %q for path %s", string(data[:l]), id)
}
return
}

0 comments on commit c803483

Please sign in to comment.