gco/gcimporter15: update importer to match new gc binary export format
This is simply a copy of std lib's go/internal/gcimporter/bimport.go with updated header comment and build tag. No semantic changes. This will fix part of the x/tools build break at tip. The other part is to adjust bexport.go (next CL). Change-Id: Ibc37fae7e0d0447fdea9e3a733aa38589735c59a Reviewed-on: https://go-review.googlesource.com/21543 Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
02e8ee6893
commit
44f369b779
|
|
@ -19,6 +19,18 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type importer struct {
|
||||||
|
imports map[string]*types.Package
|
||||||
|
data []byte
|
||||||
|
buf []byte // for reading strings
|
||||||
|
bufarray [64]byte // initial underlying array for buf, large enough to avoid allocation when compiling std lib
|
||||||
|
pkgList []*types.Package
|
||||||
|
typList []types.Type
|
||||||
|
|
||||||
|
debugFormat bool
|
||||||
|
read int // bytes read
|
||||||
|
}
|
||||||
|
|
||||||
// BImportData imports a package from the serialized package data
|
// BImportData imports a package from the serialized package data
|
||||||
// and returns the number of bytes consumed and a reference to the package.
|
// and returns the number of bytes consumed and a reference to the package.
|
||||||
// If data is obviously malformed, an error is returned but in
|
// If data is obviously malformed, an error is returned but in
|
||||||
|
|
@ -43,7 +55,7 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
|
||||||
// --- generic export data ---
|
// --- generic export data ---
|
||||||
|
|
||||||
if v := p.string(); v != "v0" {
|
if v := p.string(); v != "v0" {
|
||||||
return p.read, nil, fmt.Errorf("unknown version: %s", v)
|
return p.read, nil, fmt.Errorf("unknown export data version: %s", v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// populate typList with predeclared "known" types
|
// populate typList with predeclared "known" types
|
||||||
|
|
@ -73,37 +85,20 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
|
||||||
// read compiler-specific flags
|
// read compiler-specific flags
|
||||||
p.string() // discard
|
p.string() // discard
|
||||||
|
|
||||||
// read consts
|
// read objects of phase 1 only (see cmd/compiler/internal/gc/bexport.go)
|
||||||
for i := p.int(); i > 0; i-- {
|
objcount := 0
|
||||||
name := p.string()
|
for {
|
||||||
typ := p.typ(nil)
|
tag := p.tagOrIndex()
|
||||||
val := p.value()
|
if tag == endTag {
|
||||||
p.declare(types.NewConst(token.NoPos, pkg, name, typ, val))
|
break
|
||||||
|
}
|
||||||
|
p.obj(tag)
|
||||||
|
objcount++
|
||||||
}
|
}
|
||||||
|
|
||||||
// read vars
|
// self-verification
|
||||||
for i := p.int(); i > 0; i-- {
|
if count := p.int(); count != objcount {
|
||||||
name := p.string()
|
panic(fmt.Sprintf("importer: got %d objects; want %d", objcount, count))
|
||||||
typ := p.typ(nil)
|
|
||||||
p.declare(types.NewVar(token.NoPos, pkg, name, typ))
|
|
||||||
}
|
|
||||||
|
|
||||||
// read funcs
|
|
||||||
for i := p.int(); i > 0; i-- {
|
|
||||||
name := p.string()
|
|
||||||
params, isddd := p.paramList()
|
|
||||||
result, _ := p.paramList()
|
|
||||||
sig := types.NewSignature(nil, params, result, isddd)
|
|
||||||
p.int() // read and discard index of inlined function body
|
|
||||||
p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
|
|
||||||
}
|
|
||||||
|
|
||||||
// read types
|
|
||||||
for i := p.int(); i > 0; i-- {
|
|
||||||
// name is parsed as part of named type and the
|
|
||||||
// type object is added to scope via respective
|
|
||||||
// named type
|
|
||||||
_ = p.typ(nil).(*types.Named)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore compiler-specific import data
|
// ignore compiler-specific import data
|
||||||
|
|
@ -126,25 +121,6 @@ func BImportData(imports map[string]*types.Package, data []byte, path string) (i
|
||||||
return p.read, pkg, nil
|
return p.read, pkg, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type importer struct {
|
|
||||||
imports map[string]*types.Package
|
|
||||||
data []byte
|
|
||||||
buf []byte // for reading strings
|
|
||||||
bufarray [64]byte // initial underlying array for buf, large enough to avoid allocation when compiling std lib
|
|
||||||
pkgList []*types.Package
|
|
||||||
typList []types.Type
|
|
||||||
|
|
||||||
debugFormat bool
|
|
||||||
read int // bytes read
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *importer) declare(obj types.Object) {
|
|
||||||
if alt := p.pkgList[0].Scope().Insert(obj); alt != nil {
|
|
||||||
// This can only happen if we import a package a second time.
|
|
||||||
panic(fmt.Sprintf("%s already declared", alt.Name()))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *importer) pkg() *types.Package {
|
func (p *importer) pkg() *types.Package {
|
||||||
// if the package was seen before, i is its index (>= 0)
|
// if the package was seen before, i is its index (>= 0)
|
||||||
i := p.tagOrIndex()
|
i := p.tagOrIndex()
|
||||||
|
|
@ -182,6 +158,55 @@ func (p *importer) pkg() *types.Package {
|
||||||
return pkg
|
return pkg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *importer) declare(obj types.Object) {
|
||||||
|
pkg := obj.Pkg()
|
||||||
|
if alt := pkg.Scope().Insert(obj); alt != nil {
|
||||||
|
// This could only trigger if we import a (non-type) object a second time.
|
||||||
|
// This should never happen because 1) we only import a package once; and
|
||||||
|
// b) we ignore compiler-specific export data which may contain functions
|
||||||
|
// whose inlined function bodies refer to other functions that were already
|
||||||
|
// imported.
|
||||||
|
// (See also the comment in cmd/compile/internal/gc/bimport.go importer.obj,
|
||||||
|
// switch case importing functions).
|
||||||
|
panic(fmt.Sprintf("%s already declared", alt.Name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *importer) obj(tag int) {
|
||||||
|
switch tag {
|
||||||
|
case constTag:
|
||||||
|
pkg, name := p.qualifiedName()
|
||||||
|
typ := p.typ(nil)
|
||||||
|
val := p.value()
|
||||||
|
p.declare(types.NewConst(token.NoPos, pkg, name, typ, val))
|
||||||
|
|
||||||
|
case typeTag:
|
||||||
|
_ = p.typ(nil)
|
||||||
|
|
||||||
|
case varTag:
|
||||||
|
pkg, name := p.qualifiedName()
|
||||||
|
typ := p.typ(nil)
|
||||||
|
p.declare(types.NewVar(token.NoPos, pkg, name, typ))
|
||||||
|
|
||||||
|
case funcTag:
|
||||||
|
pkg, name := p.qualifiedName()
|
||||||
|
params, isddd := p.paramList()
|
||||||
|
result, _ := p.paramList()
|
||||||
|
sig := types.NewSignature(nil, params, result, isddd)
|
||||||
|
p.int() // read and discard index of inlined function body
|
||||||
|
p.declare(types.NewFunc(token.NoPos, pkg, name, sig))
|
||||||
|
|
||||||
|
default:
|
||||||
|
panic("unexpected object tag")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *importer) qualifiedName() (pkg *types.Package, name string) {
|
||||||
|
name = p.string()
|
||||||
|
pkg = p.pkg()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (p *importer) record(t types.Type) {
|
func (p *importer) record(t types.Type) {
|
||||||
p.typList = append(p.typList, t)
|
p.typList = append(p.typList, t)
|
||||||
}
|
}
|
||||||
|
|
@ -243,11 +268,17 @@ func (p *importer) typ(parent *types.Package) types.Type {
|
||||||
|
|
||||||
// read associated methods
|
// read associated methods
|
||||||
for i := p.int(); i > 0; i-- {
|
for i := p.int(); i > 0; i-- {
|
||||||
|
// TODO(gri) replace this with something closer to fieldName
|
||||||
name := p.string()
|
name := p.string()
|
||||||
|
if !exported(name) {
|
||||||
|
p.pkg()
|
||||||
|
}
|
||||||
|
|
||||||
recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
|
recv, _ := p.paramList() // TODO(gri) do we need a full param list for the receiver?
|
||||||
params, isddd := p.paramList()
|
params, isddd := p.paramList()
|
||||||
result, _ := p.paramList()
|
result, _ := p.paramList()
|
||||||
p.int() // read and discard index of inlined function body
|
p.int() // read and discard index of inlined function body
|
||||||
|
|
||||||
sig := types.NewSignature(recv.At(0), params, result, isddd)
|
sig := types.NewSignature(recv.At(0), params, result, isddd)
|
||||||
t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
|
t0.AddMethod(types.NewFunc(token.NoPos, parent, name, sig))
|
||||||
}
|
}
|
||||||
|
|
@ -436,18 +467,20 @@ func (p *importer) param(named bool) (*types.Var, bool) {
|
||||||
t = types.NewSlice(td.elem)
|
t = types.NewSlice(td.elem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pkg *types.Package
|
||||||
var name string
|
var name string
|
||||||
if named {
|
if named {
|
||||||
name = p.string()
|
name = p.string()
|
||||||
if name == "" {
|
if name == "" {
|
||||||
panic("expected named parameter")
|
panic("expected named parameter")
|
||||||
}
|
}
|
||||||
|
pkg = p.pkg()
|
||||||
}
|
}
|
||||||
|
|
||||||
// read and discard compiler-specific info
|
// read and discard compiler-specific info
|
||||||
p.string()
|
p.string()
|
||||||
|
|
||||||
return types.NewVar(token.NoPos, nil, name, t), isddd
|
return types.NewVar(token.NoPos, pkg, name, t), isddd
|
||||||
}
|
}
|
||||||
|
|
||||||
func exported(name string) bool {
|
func exported(name string) bool {
|
||||||
|
|
@ -471,9 +504,6 @@ func (p *importer) value() constant.Value {
|
||||||
return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
|
return constant.BinaryOp(re, token.ADD, constant.MakeImag(im))
|
||||||
case stringTag:
|
case stringTag:
|
||||||
return constant.MakeString(p.string())
|
return constant.MakeString(p.string())
|
||||||
case unknownTag:
|
|
||||||
// (Encoded package contains type errors.)
|
|
||||||
return constant.MakeUnknown()
|
|
||||||
default:
|
default:
|
||||||
panic(fmt.Sprintf("unexpected value tag %d", tag))
|
panic(fmt.Sprintf("unexpected value tag %d", tag))
|
||||||
}
|
}
|
||||||
|
|
@ -624,8 +654,13 @@ func (p *importer) byte() byte {
|
||||||
|
|
||||||
// Tags. Must be < 0.
|
// Tags. Must be < 0.
|
||||||
const (
|
const (
|
||||||
// Packages
|
// Objects
|
||||||
packageTag = -(iota + 1)
|
packageTag = -(iota + 1)
|
||||||
|
constTag
|
||||||
|
typeTag
|
||||||
|
varTag
|
||||||
|
funcTag
|
||||||
|
endTag
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
namedTag
|
namedTag
|
||||||
|
|
@ -647,7 +682,7 @@ const (
|
||||||
fractionTag // not used by gc
|
fractionTag // not used by gc
|
||||||
complexTag
|
complexTag
|
||||||
stringTag
|
stringTag
|
||||||
unknownTag // only appears in packages with errors
|
unknownTag // not used by gc (only appears in packages with errors)
|
||||||
)
|
)
|
||||||
|
|
||||||
var predeclared = []types.Type{
|
var predeclared = []types.Type{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue