mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
The binary import/export format is significantly more
compact than the existing textual format. It should
also be faster to read and write (to be measured).
Use -newexport to enable, for instance:
export GO_GCFLAGS=-newexport; make.bash
The compiler can import packages using both the old
and the new format ("mixed mode").
Missing: export info for inlined functions bodies
(performance issue, does not affect correctness).
Disabled by default until we have inlined function
bodies and confirmation of no regression and equality
of binaries.
For #6110.
For #1909.
This change depends on:
https://go-review.googlesource.com/16220
https://go-review.googlesource.com/16222
(already submitted) for all.bash to work.
Some initial export data sizes for std lib packages. This data
is without exported functions with inlineable function bodies.
Package old new new/old
archive/tar.................................13875.....3883 28%
archive/zip.................................19464.....5046 26%
bufio....................................... 7733.....2222 29%
bytes.......................................10342.....3347 32%
cmd/addr2line.................................242.......26 11%
cmd/api.....................................39305....10368 26%
cmd/asm/internal/arch.......................27732.....7939 29%
cmd/asm/internal/asm........................35264....10295 29%
cmd/asm/internal/flags........................629......178 28%
cmd/asm/internal/lex........................39248....11128 28%
cmd/asm.......................................306.......26 8%
cmd/cgo.....................................40197....10570 26%
cmd/compile/internal/amd64...................1106......214 19%
cmd/compile/internal/arm....................27891.....7710 28%
cmd/compile/internal/arm64....................891......153 17%
cmd/compile/internal/big....................21637.....8336 39%
cmd/compile/internal/gc....................109845....29727 27%
cmd/compile/internal/mips64...................972......168 17%
cmd/compile/internal/ppc64....................972......168 17%
cmd/compile/internal/x86.....................1104......195 18%
cmd/compile...................................329.......26 8%
cmd/cover...................................12986.....3749 29%
cmd/dist......................................477.......67 14%
cmd/doc.....................................23043.....6793 29%
cmd/expdump...................................167.......26 16%
cmd/fix......................................1190......208 17%
cmd/go......................................26399.....5629 21%
cmd/gofmt.....................................499.......26 5%
cmd/internal/gcprog..........................1342......490 37%
cmd/internal/goobj...........................2690......980 36%
cmd/internal/obj/arm........................32740....10057 31%
cmd/internal/obj/arm64......................46542....15364 33%
cmd/internal/obj/mips.......................42140....13731 33%
cmd/internal/obj/ppc64......................42140....13731 33%
cmd/internal/obj/x86........................52732....19015 36%
cmd/internal/obj............................36729....11690 32%
cmd/internal/objfile........................36365....10287 28%
cmd/link/internal/amd64.....................45893....12220 27%
cmd/link/internal/arm.........................307.......96 31%
cmd/link/internal/arm64.......................345.......98 28%
cmd/link/internal/ld.......................109300....46326 42%
cmd/link/internal/ppc64.......................344.......99 29%
cmd/link/internal/x86.........................334......107 32%
cmd/link......................................314.......26 8%
cmd/newlink..................................8110.....2544 31%
cmd/nm........................................210.......26 12%
cmd/objdump...................................244.......26 11%
cmd/pack....................................14248.....4066 29%
cmd/pprof/internal/commands..................5239.....1285 25%
cmd/pprof/internal/driver...................37967.....8860 23%
cmd/pprof/internal/fetch....................30962.....7337 24%
cmd/pprof/internal/plugin...................47734.....7719 16%
cmd/pprof/internal/profile..................22286.....6922 31%
cmd/pprof/internal/report...................31187.....7838 25%
cmd/pprof/internal/svg.......................4315......965 22%
cmd/pprof/internal/symbolizer...............30051.....7397 25%
cmd/pprof/internal/symbolz..................28545.....6949 24%
cmd/pprof/internal/tempfile.................12550.....3356 27%
cmd/pprof.....................................563.......26 5%
cmd/trace....................................1455......636 44%
cmd/vendor/golang.org/x/arch/arm/armasm....168035....64737 39%
cmd/vendor/golang.org/x/arch/x86/x86asm.....26871.....8578 32%
cmd/vet.....................................38980.....9913 25%
cmd/vet/whitelist.............................102.......49 48%
cmd/yacc.....................................2518......926 37%
compress/bzip2...............................6326......129 2%
compress/flate...............................7069.....2541 36%
compress/gzip...............................20143.....5069 25%
compress/lzw..................................828......295 36%
compress/zlib...............................10676.....2692 25%
container/heap................................523......181 35%
container/list...............................3517......740 21%
container/ring................................881......229 26%
crypto/aes....................................550......187 34%
crypto/cipher................................1966......825 42%
crypto.......................................1836......646 35%
crypto/des....................................632......235 37%
crypto/dsa..................................18718.....5035 27%
crypto/ecdsa................................23131.....6097 26%
crypto/elliptic.............................20790.....5740 28%
crypto/hmac...................................455......186 41%
crypto/md5...................................1375......171 12%
crypto/rand.................................18132.....4748 26%
crypto/rc4....................................561......240 43%
crypto/rsa..................................22094.....6380 29%
crypto/sha1..................................1416......172 12%
crypto/sha256.................................551......238 43%
crypto/sha512.................................839......378 45%
crypto/subtle................................1153......250 22%
crypto/tls..................................58203....17984 31%
crypto/x509/pkix............................29447.....8161 28%
database/sql/driver..........................3318.....1096 33%
database/sql................................11258.....3942 35%
debug/dwarf.................................18416.....7006 38%
debug/elf...................................57530....21014 37%
debug/gosym..................................4992.....2058 41%
debug/macho.................................23037.....6538 28%
debug/pe....................................21063.....6619 31%
debug/plan9obj...............................2467......802 33%
encoding/ascii85.............................1523......360 24%
encoding/asn1................................1718......527 31%
encoding/base32..............................2642......686 26%
encoding/base64..............................3077......800 26%
encoding/binary..............................4727.....1040 22%
encoding/csv................................12223.....2850 23%
encoding......................................383......217 57%
encoding/gob................................37563....10113 27%
encoding/hex.................................1327......390 29%
encoding/json...............................30897.....7804 25%
encoding/pem..................................595......200 34%
encoding/xml................................37798.....9336 25%
errors........................................274.......36 13%
expvar.......................................3155.....1021 32%
flag........................................19860.....2849 14%
fmt..........................................3137.....1263 40%
go/ast......................................44729....13422 30%
go/build....................................16336.....4657 29%
go/constant..................................3703......846 23%
go/doc.......................................9877.....2807 28%
go/format....................................5472.....1575 29%
go/importer..................................4980.....1301 26%
go/internal/gccgoimporter....................5587.....1525 27%
go/internal/gcimporter.......................8979.....2186 24%
go/parser...................................20692.....5304 26%
go/printer...................................7015.....2029 29%
go/scanner...................................9719.....2824 29%
go/token.....................................7933.....2465 31%
go/types....................................64569....19978 31%
hash/adler32.................................1176......176 15%
hash/crc32...................................1663......360 22%
hash/crc64...................................1587......306 19%
hash/fnv.....................................3964......260 7%
hash..........................................591......278 47%
html..........................................217.......74 34%
html/template...............................69623....12588 18%
image/color/palette...........................315.......98 31%
image/color..................................5565.....1036 19%
image/draw...................................6917.....1028 15%
image/gif....................................8894.....1654 19%
image/internal/imageutil.....................9112.....1476 16%
image/jpeg...................................6647.....1026 15%
image/png....................................6906.....1069 15%
image.......................................28992.....6139 21%
index/suffixarray...........................17106.....4773 28%
internal/singleflight........................1614......506 31%
internal/testenv............................12212.....3152 26%
internal/trace...............................2762.....1323 48%
io/ioutil...................................13502.....3682 27%
io...........................................6765.....2482 37%
log.........................................11620.....3317 29%
log/syslog..................................13516.....3821 28%
math/big....................................21819.....8320 38%
math/cmplx...................................2816......438 16%
math/rand....................................2317......929 40%
math.........................................7511.....2444 33%
mime/multipart..............................12679.....3360 27%
mime/quotedprintable.........................5458.....1235 23%
mime.........................................6076.....1628 27%
net/http/cgi................................59796....17173 29%
net/http/cookiejar..........................14781.....3739 25%
net/http/fcgi...............................57861....16426 28%
net/http/httptest...........................84100....24365 29%
net/http/httputil...........................67763....18869 28%
net/http/internal............................6907......637 9%
net/http/pprof..............................57945....16316 28%
net/http....................................95391....30210 32%
net/internal/socktest........................4555.....1453 32%
net/mail....................................14481.....3608 25%
net/rpc/jsonrpc.............................33335......988 3%
net/rpc.....................................79950....23106 29%
net/smtp....................................57790....16468 28%
net/textproto...............................11356.....3248 29%
net/url......................................3123.....1009 32%
os/exec.....................................20738.....5769 28%
os/signal.....................................437......167 38%
os..........................................24875.....6668 27%
path/filepath...............................11340.....2826 25%
path..........................................778......285 37%
reflect.....................................15469.....5198 34%
regexp......................................13627.....4661 34%
regexp/syntax................................5539.....2249 41%
runtime/debug................................9275.....2322 25%
runtime/pprof................................1355......477 35%
runtime/race...................................39.......17 44%
runtime/trace.................................228.......92 40%
runtime.....................................13498.....1821 13%
sort.........................................2848......842 30%
strconv......................................2947.....1252 42%
strings......................................7983.....2456 31%
sync/atomic..................................2666.....1149 43%
sync.........................................2568......845 33%
syscall.....................................81252....38398 47%
testing/iotest...............................2444......302 12%
testing/quick...............................18890.....5076 27%
testing.....................................16502.....4800 29%
text/scanner.................................6849.....2052 30%
text/tabwriter...............................6607.....1863 28%
text/template/parse.........................22978.....6183 27%
text/template...............................64153....11518 18%
time........................................12103.....3546 29%
unicode......................................9706.....3320 34%
unicode/utf16................................1055......148 14%
unicode/utf8.................................1118......513 46%
vendor/golang.org/x/net/http2/hpack..........8905.....2636 30%
All packages 3518505 1017774 29%
Change-Id: Id657334f276383ff1e6fa91472d3d1db5a03349c
Reviewed-on: https://go-review.googlesource.com/13937
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Chris Manghane <cmang@golang.org>
619 lines
12 KiB
Go
619 lines
12 KiB
Go
// Copyright 2015 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.
|
|
|
|
// Binary package import.
|
|
// Based loosely on x/tools/go/importer.
|
|
|
|
package gc
|
|
|
|
import (
|
|
"cmd/compile/internal/big"
|
|
"cmd/internal/obj"
|
|
"encoding/binary"
|
|
)
|
|
|
|
// The overall structure of Import is symmetric to Export: For each
|
|
// export method in bexport.go there is a matching and symmetric method
|
|
// in bimport.go. Changing the export format requires making symmetric
|
|
// changes to bimport.go and bexport.go.
|
|
|
|
// Import populates importpkg from the serialized package data.
|
|
func Import(in *obj.Biobuf) {
|
|
p := importer{in: in}
|
|
p.buf = p.bufarray[:]
|
|
|
|
// read low-level encoding format
|
|
switch format := p.byte(); format {
|
|
case 'c':
|
|
// compact format - nothing to do
|
|
case 'd':
|
|
p.debugFormat = true
|
|
default:
|
|
Fatalf("invalid encoding format in export data: got %q; want 'c' or 'd'", format)
|
|
}
|
|
|
|
// --- generic export data ---
|
|
|
|
if v := p.string(); v != exportVersion {
|
|
Fatalf("unknown export data version: %s", v)
|
|
}
|
|
|
|
// populate typList with predeclared "known" types
|
|
p.typList = append(p.typList, predeclared()...)
|
|
|
|
// read package data
|
|
p.pkg()
|
|
if p.pkgList[0] != importpkg {
|
|
Fatalf("imported package not found in pkgList[0]")
|
|
}
|
|
|
|
// read compiler-specific flags
|
|
importpkg.Safe = p.string() == "safe"
|
|
|
|
// defer some type-checking until all types are read in completely
|
|
// (go.y:import_there)
|
|
tcok := typecheckok
|
|
typecheckok = true
|
|
defercheckwidth()
|
|
|
|
// read consts
|
|
for i := p.int(); i > 0; i-- {
|
|
sym := p.localname()
|
|
typ := p.typ()
|
|
val := p.value(typ)
|
|
if isideal(typ) {
|
|
// canonicalize ideal types
|
|
typ = Types[TIDEAL]
|
|
}
|
|
importconst(sym, typ, nodlit(val))
|
|
}
|
|
|
|
// read vars
|
|
for i := p.int(); i > 0; i-- {
|
|
sym := p.localname()
|
|
typ := p.typ()
|
|
importvar(sym, typ)
|
|
}
|
|
|
|
// read funcs
|
|
for i := p.int(); i > 0; i-- {
|
|
// go.y:hidden_fndcl
|
|
sym := p.localname()
|
|
typ := p.typ()
|
|
// TODO(gri) fix this
|
|
p.int() // read and discard index of inlined function body for now
|
|
|
|
importsym(sym, ONAME)
|
|
if sym.Def != nil && sym.Def.Op == ONAME && !Eqtype(typ, sym.Def.Type) {
|
|
Fatalf("inconsistent definition for func %v during import\n\t%v\n\t%v", sym, sym.Def.Type, typ)
|
|
}
|
|
|
|
n := newfuncname(sym)
|
|
n.Type = typ
|
|
declare(n, PFUNC)
|
|
funchdr(n)
|
|
|
|
// go.y:hidden_import
|
|
n.Func.Inl = nil
|
|
funcbody(n)
|
|
importlist = append(importlist, n) // TODO(gri) do this only if body is inlineable?
|
|
}
|
|
|
|
// read types
|
|
for i := p.int(); i > 0; i-- {
|
|
// name is parsed as part of named type
|
|
p.typ()
|
|
}
|
|
|
|
// --- compiler-specific export data ---
|
|
|
|
for i := p.int(); i > 0; i-- {
|
|
p.body()
|
|
}
|
|
|
|
// --- end of export data ---
|
|
|
|
typecheckok = tcok
|
|
resumecheckwidth()
|
|
|
|
testdclstack() // debugging only
|
|
}
|
|
|
|
type importer struct {
|
|
in *obj.Biobuf
|
|
buf []byte // for reading strings
|
|
bufarray [64]byte // initial underlying array for buf, large enough to avoid allocation when compiling std lib
|
|
pkgList []*Pkg
|
|
typList []*Type
|
|
|
|
debugFormat bool
|
|
read int // bytes read
|
|
}
|
|
|
|
func (p *importer) pkg() *Pkg {
|
|
// if the package was seen before, i is its index (>= 0)
|
|
i := p.tagOrIndex()
|
|
if i >= 0 {
|
|
return p.pkgList[i]
|
|
}
|
|
|
|
// otherwise, i is the package tag (< 0)
|
|
if i != packageTag {
|
|
Fatalf("expected package tag, found tag = %d", i)
|
|
}
|
|
|
|
// read package data
|
|
name := p.string()
|
|
path := p.string()
|
|
|
|
// we should never see an empty package name
|
|
if name == "" {
|
|
Fatalf("empty package name in import")
|
|
}
|
|
|
|
// we should never see a bad import path
|
|
if isbadimport(path) {
|
|
Fatalf("bad path in import: %q", path)
|
|
}
|
|
|
|
// an empty path denotes the package we are currently importing
|
|
pkg := importpkg
|
|
if path != "" {
|
|
pkg = mkpkg(path)
|
|
}
|
|
if pkg.Name == "" {
|
|
pkg.Name = name
|
|
} else if pkg.Name != name {
|
|
Fatalf("inconsistent package names: got %s; want %s (path = %s)", pkg.Name, name, path)
|
|
}
|
|
p.pkgList = append(p.pkgList, pkg)
|
|
|
|
return pkg
|
|
}
|
|
|
|
func (p *importer) localname() *Sym {
|
|
// go.y:hidden_importsym
|
|
name := p.string()
|
|
if name == "" {
|
|
Fatalf("unexpected anonymous name")
|
|
}
|
|
structpkg = importpkg // go.y:hidden_pkg_importsym
|
|
return importpkg.Lookup(name)
|
|
}
|
|
|
|
func (p *importer) newtyp(etype int) *Type {
|
|
t := typ(etype)
|
|
p.typList = append(p.typList, t)
|
|
return t
|
|
}
|
|
|
|
func (p *importer) typ() *Type {
|
|
// if the type was seen before, i is its index (>= 0)
|
|
i := p.tagOrIndex()
|
|
if i >= 0 {
|
|
return p.typList[i]
|
|
}
|
|
|
|
// otherwise, i is the type tag (< 0)
|
|
var t *Type
|
|
switch i {
|
|
case namedTag:
|
|
// go.y:hidden_importsym
|
|
tsym := p.qualifiedName()
|
|
|
|
// go.y:hidden_pkgtype
|
|
t = pkgtype(tsym)
|
|
importsym(tsym, OTYPE)
|
|
p.typList = append(p.typList, t)
|
|
|
|
// read underlying type
|
|
// go.y:hidden_type
|
|
t0 := p.typ()
|
|
importtype(t, t0) // go.y:hidden_import
|
|
|
|
// interfaces don't have associated methods
|
|
if t0.Etype == TINTER {
|
|
break
|
|
}
|
|
|
|
// read associated methods
|
|
for i := p.int(); i > 0; i-- {
|
|
// go.y:hidden_fndcl
|
|
name := p.string()
|
|
recv := p.paramList() // TODO(gri) do we need a full param list for the receiver?
|
|
params := p.paramList()
|
|
result := p.paramList()
|
|
// TODO(gri) fix this
|
|
p.int() // read and discard index of inlined function body for now
|
|
|
|
pkg := localpkg
|
|
if !exportname(name) {
|
|
pkg = tsym.Pkg
|
|
}
|
|
sym := pkg.Lookup(name)
|
|
|
|
n := methodname1(newname(sym), recv.N.Right)
|
|
n.Type = functype(recv.N, params, result)
|
|
checkwidth(n.Type)
|
|
// addmethod uses the global variable structpkg to verify consistency
|
|
{
|
|
saved := structpkg
|
|
structpkg = tsym.Pkg
|
|
addmethod(sym, n.Type, false, nointerface)
|
|
structpkg = saved
|
|
}
|
|
nointerface = false
|
|
funchdr(n)
|
|
|
|
// (comment from go.y)
|
|
// inl.C's inlnode in on a dotmeth node expects to find the inlineable body as
|
|
// (dotmeth's type).Nname.Inl, and dotmeth's type has been pulled
|
|
// out by typecheck's lookdot as this $$.ttype. So by providing
|
|
// this back link here we avoid special casing there.
|
|
n.Type.Nname = n
|
|
|
|
// go.y:hidden_import
|
|
n.Func.Inl = nil
|
|
funcbody(n)
|
|
importlist = append(importlist, n) // TODO(gri) do this only if body is inlineable?
|
|
}
|
|
|
|
case arrayTag, sliceTag:
|
|
t = p.newtyp(TARRAY)
|
|
t.Bound = -1
|
|
if i == arrayTag {
|
|
t.Bound = p.int64()
|
|
}
|
|
t.Type = p.typ()
|
|
|
|
case dddTag:
|
|
t = p.newtyp(T_old_DARRAY)
|
|
t.Bound = -1
|
|
t.Type = p.typ()
|
|
|
|
case structTag:
|
|
t = p.newtyp(TSTRUCT)
|
|
tostruct0(t, p.fieldList())
|
|
|
|
case pointerTag:
|
|
t = p.newtyp(Tptr)
|
|
t.Type = p.typ()
|
|
|
|
case signatureTag:
|
|
t = p.newtyp(TFUNC)
|
|
params := p.paramList()
|
|
result := p.paramList()
|
|
functype0(t, nil, params, result)
|
|
|
|
case interfaceTag:
|
|
t = p.newtyp(TINTER)
|
|
if p.int() != 0 {
|
|
Fatalf("unexpected embedded interface")
|
|
}
|
|
tointerface0(t, p.methodList())
|
|
|
|
case mapTag:
|
|
t = p.newtyp(TMAP)
|
|
t.Down = p.typ() // key
|
|
t.Type = p.typ() // val
|
|
|
|
case chanTag:
|
|
t = p.newtyp(TCHAN)
|
|
t.Chan = uint8(p.int())
|
|
t.Type = p.typ()
|
|
|
|
default:
|
|
Fatalf("unexpected type (tag = %d)", i)
|
|
}
|
|
|
|
if t == nil {
|
|
Fatalf("nil type (type tag = %d)", i)
|
|
}
|
|
|
|
return t
|
|
}
|
|
|
|
func (p *importer) qualifiedName() *Sym {
|
|
name := p.string()
|
|
pkg := p.pkg()
|
|
return pkg.Lookup(name)
|
|
}
|
|
|
|
// go.y:hidden_structdcl_list
|
|
func (p *importer) fieldList() *NodeList {
|
|
i := p.int()
|
|
if i == 0 {
|
|
return nil
|
|
}
|
|
n := list1(p.field())
|
|
for i--; i > 0; i-- {
|
|
n = list(n, p.field())
|
|
}
|
|
return n
|
|
}
|
|
|
|
// go.y:hidden_structdcl
|
|
func (p *importer) field() *Node {
|
|
sym := p.fieldName()
|
|
typ := p.typ()
|
|
note := p.note()
|
|
|
|
var n *Node
|
|
if sym.Name != "" {
|
|
n = Nod(ODCLFIELD, newname(sym), typenod(typ))
|
|
} else {
|
|
// anonymous field - typ must be T or *T and T must be a type name
|
|
s := typ.Sym
|
|
if s == nil && Isptr[typ.Etype] {
|
|
s = typ.Type.Sym // deref
|
|
}
|
|
pkg := importpkg
|
|
if sym != nil {
|
|
pkg = sym.Pkg
|
|
}
|
|
n = embedded(s, pkg)
|
|
n.Right = typenod(typ)
|
|
}
|
|
n.SetVal(note)
|
|
|
|
return n
|
|
}
|
|
|
|
func (p *importer) note() (v Val) {
|
|
if s := p.string(); s != "" {
|
|
v.U = s
|
|
}
|
|
return
|
|
}
|
|
|
|
// go.y:hidden_interfacedcl_list
|
|
func (p *importer) methodList() *NodeList {
|
|
i := p.int()
|
|
if i == 0 {
|
|
return nil
|
|
}
|
|
n := list1(p.method())
|
|
for i--; i > 0; i-- {
|
|
n = list(n, p.method())
|
|
}
|
|
return n
|
|
}
|
|
|
|
// go.y:hidden_interfacedcl
|
|
func (p *importer) method() *Node {
|
|
sym := p.fieldName()
|
|
params := p.paramList()
|
|
result := p.paramList()
|
|
return Nod(ODCLFIELD, newname(sym), typenod(functype(fakethis(), params, result)))
|
|
}
|
|
|
|
// go.y:sym,hidden_importsym
|
|
func (p *importer) fieldName() *Sym {
|
|
name := p.string()
|
|
pkg := localpkg
|
|
if name == "_" {
|
|
// During imports, unqualified non-exported identifiers are from builtinpkg
|
|
// (see go.y:sym). The binary exporter only exports blank as a non-exported
|
|
// identifier without qualification.
|
|
pkg = builtinpkg
|
|
} else if name == "?" || name != "" && !exportname(name) {
|
|
if name == "?" {
|
|
name = ""
|
|
}
|
|
pkg = p.pkg()
|
|
}
|
|
return pkg.Lookup(name)
|
|
}
|
|
|
|
// go.y:ohidden_funarg_list
|
|
func (p *importer) paramList() *NodeList {
|
|
i := p.int()
|
|
if i == 0 {
|
|
return nil
|
|
}
|
|
// negative length indicates unnamed parameters
|
|
named := true
|
|
if i < 0 {
|
|
i = -i
|
|
named = false
|
|
}
|
|
// i > 0
|
|
n := list1(p.param(named))
|
|
i--
|
|
for ; i > 0; i-- {
|
|
n = list(n, p.param(named))
|
|
}
|
|
return n
|
|
}
|
|
|
|
// go.y:hidden_funarg
|
|
func (p *importer) param(named bool) *Node {
|
|
typ := p.typ()
|
|
|
|
isddd := false
|
|
if typ.Etype == T_old_DARRAY {
|
|
// T_old_DARRAY indicates ... type
|
|
typ.Etype = TARRAY
|
|
isddd = true
|
|
}
|
|
|
|
n := Nod(ODCLFIELD, nil, typenod(typ))
|
|
n.Isddd = isddd
|
|
|
|
if named {
|
|
name := p.string()
|
|
if name == "" {
|
|
Fatalf("expected named parameter")
|
|
}
|
|
// The parameter package doesn't matter; it's never consulted.
|
|
// We use the builtinpkg per go.y:sym (line 1181).
|
|
n.Left = newname(builtinpkg.Lookup(name))
|
|
}
|
|
|
|
// TODO(gri) This is compiler-specific (escape info).
|
|
// Move into compiler-specific section eventually?
|
|
n.SetVal(p.note())
|
|
|
|
return n
|
|
}
|
|
|
|
func (p *importer) value(typ *Type) (x Val) {
|
|
switch tag := p.tagOrIndex(); tag {
|
|
case falseTag:
|
|
x.U = false
|
|
case trueTag:
|
|
x.U = true
|
|
case int64Tag:
|
|
u := new(Mpint)
|
|
Mpmovecfix(u, p.int64())
|
|
u.Rune = typ == idealrune
|
|
x.U = u
|
|
case floatTag:
|
|
f := newMpflt()
|
|
p.float(f)
|
|
if typ == idealint || Isint[typ.Etype] {
|
|
// uncommon case: large int encoded as float
|
|
u := new(Mpint)
|
|
mpmovefltfix(u, f)
|
|
x.U = u
|
|
break
|
|
}
|
|
x.U = f
|
|
case complexTag:
|
|
u := new(Mpcplx)
|
|
p.float(&u.Real)
|
|
p.float(&u.Imag)
|
|
x.U = u
|
|
case stringTag:
|
|
x.U = p.string()
|
|
default:
|
|
Fatalf("unexpected value tag %d", tag)
|
|
}
|
|
|
|
// verify ideal type
|
|
if isideal(typ) && untype(x.Ctype()) != typ {
|
|
Fatalf("value %v and type %v don't match", x, typ)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (p *importer) float(x *Mpflt) {
|
|
sign := p.int()
|
|
if sign == 0 {
|
|
Mpmovecflt(x, 0)
|
|
return
|
|
}
|
|
|
|
exp := p.int()
|
|
mant := new(big.Int).SetBytes([]byte(p.string()))
|
|
|
|
m := x.Val.SetInt(mant)
|
|
m.SetMantExp(m, exp-mant.BitLen())
|
|
if sign < 0 {
|
|
m.Neg(m)
|
|
}
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Inlined function bodies
|
|
|
|
func (p *importer) body() {
|
|
p.int()
|
|
p.block()
|
|
}
|
|
|
|
func (p *importer) block() {
|
|
for i := p.int(); i > 0; i-- {
|
|
p.stmt()
|
|
}
|
|
}
|
|
|
|
func (p *importer) stmt() {
|
|
// TODO(gri) do something sensible here
|
|
p.string()
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Low-level decoders
|
|
|
|
func (p *importer) tagOrIndex() int {
|
|
if p.debugFormat {
|
|
p.marker('t')
|
|
}
|
|
|
|
return int(p.rawInt64())
|
|
}
|
|
|
|
func (p *importer) int() int {
|
|
x := p.int64()
|
|
if int64(int(x)) != x {
|
|
Fatalf("exported integer too large")
|
|
}
|
|
return int(x)
|
|
}
|
|
|
|
func (p *importer) int64() int64 {
|
|
if p.debugFormat {
|
|
p.marker('i')
|
|
}
|
|
|
|
return p.rawInt64()
|
|
}
|
|
|
|
func (p *importer) string() string {
|
|
if p.debugFormat {
|
|
p.marker('s')
|
|
}
|
|
|
|
if n := int(p.rawInt64()); n > 0 {
|
|
if cap(p.buf) < n {
|
|
p.buf = make([]byte, n)
|
|
} else {
|
|
p.buf = p.buf[:n]
|
|
}
|
|
r := obj.Bread(p.in, p.buf)
|
|
p.read += r
|
|
if r != n {
|
|
Fatalf("read error: read %d bytes of %d", r, n)
|
|
}
|
|
return string(p.buf)
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
func (p *importer) marker(want byte) {
|
|
if got := p.byte(); got != want {
|
|
Fatalf("incorrect marker: got %c; want %c (pos = %d)", got, want, p.read)
|
|
}
|
|
|
|
pos := p.read
|
|
if n := int(p.rawInt64()); n != pos {
|
|
Fatalf("incorrect position: got %d; want %d", n, pos)
|
|
}
|
|
}
|
|
|
|
func (p *importer) byte() byte {
|
|
if c := obj.Bgetc(p.in); c >= 0 {
|
|
p.read++
|
|
return byte(c)
|
|
}
|
|
Fatalf("read error")
|
|
return 0
|
|
}
|
|
|
|
// rawInt64 should only be used by low-level decoders
|
|
func (p *importer) rawInt64() int64 {
|
|
i, err := binary.ReadVarint(p)
|
|
if err != nil {
|
|
Fatalf("read error: %v", err)
|
|
}
|
|
return i
|
|
}
|
|
|
|
// needed for binary.ReadVarint in rawInt64
|
|
func (p *importer) ReadByte() (byte, error) {
|
|
return p.byte(), nil
|
|
}
|