mirror of
https://github.com/golang/go
synced 2024-11-17 15:54:39 -07:00
cmd/compile: simplify asmhdr and plugin exports handling
This CL removes a bunch of obsolete code, which made the overall possible data flow of the compiler much harder to understand. In particular, it: 1. Removes typecheck.Declare by inlining its only two remaining uses, and simplifying them down to just the couple of relevant assignments for each remaining caller. 2. Renames ir.Package.{Asms,Exports} to {AsmHdrDecls,PluginExports}, respectively, to better describe what they're used for. In particular, PluginExports now actually holds only the subset of Exports that used to be confusingly called "ptabs" in package reflectdata. 3. Renames reflectdata.WriteTabs to reflectdata.WritePluginTable, to make it clearer what it does. 4. Removes the consistency checks on len(Exports) and len(ptabs), since now it's plainly obvious that only the unified importer ever appends to PluginExports. Change-Id: Iedc9d0a4e7648de4e734f7e3e7df302580fed542 Reviewed-on: https://go-review.googlesource.com/c/go/+/518757 Reviewed-by: Keith Randall <khr@google.com> Auto-Submit: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
parent
61719e18f7
commit
f47cfd6cb5
@ -21,7 +21,7 @@ func dumpasmhdr() {
|
||||
base.Fatalf("%v", err)
|
||||
}
|
||||
fmt.Fprintf(b, "// generated by compile -asmhdr from package %s\n\n", types.LocalPkg.Name)
|
||||
for _, n := range typecheck.Target.Asms {
|
||||
for _, n := range typecheck.Target.AsmHdrDecls {
|
||||
if n.Sym().IsBlank() {
|
||||
continue
|
||||
}
|
||||
|
@ -269,9 +269,7 @@ func Main(archInit func(*ssagen.ArchInfo)) {
|
||||
ir.CurFunc = nil
|
||||
|
||||
// Build init task, if needed.
|
||||
if initTask := pkginit.Task(); initTask != nil {
|
||||
typecheck.Export(initTask)
|
||||
}
|
||||
pkginit.MakeTask()
|
||||
|
||||
// Generate ABI wrappers. Must happen before escape analysis
|
||||
// and doesn't benefit from dead-coding or inlining.
|
||||
|
@ -113,12 +113,9 @@ func dumpdata() {
|
||||
numExterns := len(typecheck.Target.Externs)
|
||||
numDecls := len(typecheck.Target.Funcs)
|
||||
dumpglobls(typecheck.Target.Externs)
|
||||
reflectdata.CollectPTabs()
|
||||
numExports := len(typecheck.Target.Exports)
|
||||
addsignats(typecheck.Target.Externs)
|
||||
reflectdata.WriteRuntimeTypes()
|
||||
reflectdata.WriteTabs()
|
||||
numPTabs := reflectdata.CountPTabs()
|
||||
reflectdata.WritePluginTable()
|
||||
reflectdata.WriteImportStrings()
|
||||
reflectdata.WriteBasicTypes()
|
||||
dumpembeds()
|
||||
@ -154,14 +151,6 @@ func dumpdata() {
|
||||
|
||||
staticdata.WriteFuncSyms()
|
||||
addGCLocals()
|
||||
|
||||
if numExports != len(typecheck.Target.Exports) {
|
||||
base.Fatalf("Target.Exports changed after compile functions loop")
|
||||
}
|
||||
newNumPTabs := reflectdata.CountPTabs()
|
||||
if newNumPTabs != numPTabs {
|
||||
base.Fatalf("ptabs changed after compile functions loop")
|
||||
}
|
||||
}
|
||||
|
||||
func dumpLinkerObj(bout *bio.Writer) {
|
||||
|
@ -27,8 +27,10 @@ type Package struct {
|
||||
// declared at package scope.
|
||||
Externs []*Name
|
||||
|
||||
// Assembly function declarations.
|
||||
Asms []*Name
|
||||
// AsmHdrDecls holds declared constants and struct types that should
|
||||
// be included in -asmhdr output. It's only populated when -asmhdr
|
||||
// is set.
|
||||
AsmHdrDecls []*Name
|
||||
|
||||
// Cgo directives.
|
||||
CgoPragmas [][]string
|
||||
@ -36,6 +38,9 @@ type Package struct {
|
||||
// Variables with //go:embed lines.
|
||||
Embeds []*Name
|
||||
|
||||
// Exported (or re-exported) symbols.
|
||||
Exports []*Name
|
||||
// PluginExports holds exported functions and variables that are
|
||||
// accessible through the package plugin API. It's only populated
|
||||
// for -buildmode=plugin (i.e., compiling package main and -dynlink
|
||||
// is set).
|
||||
PluginExports []*Name
|
||||
}
|
||||
|
@ -3418,15 +3418,15 @@ func (r *reader) pkgObjs(target *ir.Package) []*ir.Name {
|
||||
}
|
||||
}
|
||||
|
||||
if types.IsExported(sym.Name) {
|
||||
if base.Ctxt.Flag_dynlink && types.LocalPkg.Name == "main" && types.IsExported(sym.Name) && name.Op() == ir.ONAME {
|
||||
assert(!sym.OnExportList())
|
||||
target.Exports = append(target.Exports, name)
|
||||
target.PluginExports = append(target.PluginExports, name)
|
||||
sym.SetOnExportList(true)
|
||||
}
|
||||
|
||||
if base.Flag.AsmHdr != "" {
|
||||
if base.Flag.AsmHdr != "" && (name.Op() == ir.OLITERAL || name.Op() == ir.OTYPE) {
|
||||
assert(!sym.Asm())
|
||||
target.Asms = append(target.Asms, name)
|
||||
target.AsmHdrDecls = append(target.AsmHdrDecls, name)
|
||||
sym.SetAsm(true)
|
||||
}
|
||||
}
|
||||
|
@ -81,13 +81,13 @@ func MakeInit() {
|
||||
typecheck.InitTodoFunc = nil
|
||||
}
|
||||
|
||||
// Task makes and returns an initialization record for the package.
|
||||
// MakeTask makes an initialization record for the package, if necessary.
|
||||
// See runtime/proc.go:initTask for its layout.
|
||||
// The 3 tasks for initialization are:
|
||||
// 1. Initialize all of the packages the current package depends on.
|
||||
// 2. Initialize all the variables that have initializers.
|
||||
// 3. Run any init functions.
|
||||
func Task() *ir.Name {
|
||||
func MakeTask() {
|
||||
var deps []*obj.LSym // initTask records for packages the current package depends on
|
||||
var fns []*obj.LSym // functions to call for package initialization
|
||||
|
||||
@ -188,7 +188,7 @@ func Task() *ir.Name {
|
||||
}
|
||||
|
||||
if len(deps) == 0 && len(fns) == 0 && types.LocalPkg.Path != "main" && types.LocalPkg.Path != "runtime" {
|
||||
return nil // nothing to initialize
|
||||
return // nothing to initialize
|
||||
}
|
||||
|
||||
// Make an .inittask structure.
|
||||
@ -216,7 +216,6 @@ func Task() *ir.Name {
|
||||
// An initTask has pointers, but none into the Go heap.
|
||||
// It's not quite read only, the state field must be modifiable.
|
||||
objw.Global(lsym, int32(ot), obj.NOPTR)
|
||||
return task
|
||||
}
|
||||
|
||||
// initRequiredForCoverage returns TRUE if we need to force creation
|
||||
|
@ -32,10 +32,6 @@ type ptabEntry struct {
|
||||
t *types.Type
|
||||
}
|
||||
|
||||
func CountPTabs() int {
|
||||
return len(ptabs)
|
||||
}
|
||||
|
||||
// runtime interface and reflection data structures
|
||||
var (
|
||||
// protects signatset and signatslice
|
||||
@ -47,8 +43,6 @@ var (
|
||||
|
||||
gcsymmu sync.Mutex // protects gcsymset and gcsymslice
|
||||
gcsymset = make(map[*types.Type]struct{})
|
||||
|
||||
ptabs []*ir.Name
|
||||
)
|
||||
|
||||
type typeSig struct {
|
||||
@ -1352,39 +1346,41 @@ func writeITab(lsym *obj.LSym, typ, iface *types.Type, allowNonImplement bool) {
|
||||
lsym.Set(obj.AttrContentAddressable, true)
|
||||
}
|
||||
|
||||
func WriteTabs() {
|
||||
// process ptabs
|
||||
if types.LocalPkg.Name == "main" && len(ptabs) > 0 {
|
||||
ot := 0
|
||||
s := base.Ctxt.Lookup("go:plugin.tabs")
|
||||
for _, p := range ptabs {
|
||||
// Dump ptab symbol into go.pluginsym package.
|
||||
//
|
||||
// type ptab struct {
|
||||
// name nameOff
|
||||
// typ typeOff // pointer to symbol
|
||||
// }
|
||||
nsym := dname(p.Sym().Name, "", nil, true, false)
|
||||
t := p.Type()
|
||||
if p.Class != ir.PFUNC {
|
||||
t = types.NewPtr(t)
|
||||
}
|
||||
tsym := writeType(t)
|
||||
ot = objw.SymPtrOff(s, ot, nsym)
|
||||
ot = objw.SymPtrOff(s, ot, tsym)
|
||||
// Plugin exports symbols as interfaces. Mark their types
|
||||
// as UsedInIface.
|
||||
tsym.Set(obj.AttrUsedInIface, true)
|
||||
}
|
||||
objw.Global(s, int32(ot), int16(obj.RODATA))
|
||||
|
||||
ot = 0
|
||||
s = base.Ctxt.Lookup("go:plugin.exports")
|
||||
for _, p := range ptabs {
|
||||
ot = objw.SymPtr(s, ot, p.Linksym(), 0)
|
||||
}
|
||||
objw.Global(s, int32(ot), int16(obj.RODATA))
|
||||
func WritePluginTable() {
|
||||
ptabs := typecheck.Target.PluginExports
|
||||
if len(ptabs) == 0 {
|
||||
return
|
||||
}
|
||||
|
||||
lsym := base.Ctxt.Lookup("go:plugin.tabs")
|
||||
ot := 0
|
||||
for _, p := range ptabs {
|
||||
// Dump ptab symbol into go.pluginsym package.
|
||||
//
|
||||
// type ptab struct {
|
||||
// name nameOff
|
||||
// typ typeOff // pointer to symbol
|
||||
// }
|
||||
nsym := dname(p.Sym().Name, "", nil, true, false)
|
||||
t := p.Type()
|
||||
if p.Class != ir.PFUNC {
|
||||
t = types.NewPtr(t)
|
||||
}
|
||||
tsym := writeType(t)
|
||||
ot = objw.SymPtrOff(lsym, ot, nsym)
|
||||
ot = objw.SymPtrOff(lsym, ot, tsym)
|
||||
// Plugin exports symbols as interfaces. Mark their types
|
||||
// as UsedInIface.
|
||||
tsym.Set(obj.AttrUsedInIface, true)
|
||||
}
|
||||
objw.Global(lsym, int32(ot), int16(obj.RODATA))
|
||||
|
||||
lsym = base.Ctxt.Lookup("go:plugin.exports")
|
||||
ot = 0
|
||||
for _, p := range ptabs {
|
||||
ot = objw.SymPtr(lsym, ot, p.Linksym(), 0)
|
||||
}
|
||||
objw.Global(lsym, int32(ot), int16(obj.RODATA))
|
||||
}
|
||||
|
||||
func WriteImportStrings() {
|
||||
@ -1754,30 +1750,6 @@ func ZeroAddr(size int64) ir.Node {
|
||||
return typecheck.Expr(typecheck.NodAddr(x))
|
||||
}
|
||||
|
||||
func CollectPTabs() {
|
||||
if !base.Ctxt.Flag_dynlink || types.LocalPkg.Name != "main" {
|
||||
return
|
||||
}
|
||||
for _, exportn := range typecheck.Target.Exports {
|
||||
s := exportn.Sym()
|
||||
nn := ir.AsNode(s.Def)
|
||||
if nn == nil {
|
||||
continue
|
||||
}
|
||||
if nn.Op() != ir.ONAME {
|
||||
continue
|
||||
}
|
||||
n := nn.(*ir.Name)
|
||||
if !types.IsExported(s.Name) {
|
||||
continue
|
||||
}
|
||||
if s.Pkg.Name != "main" {
|
||||
continue
|
||||
}
|
||||
ptabs = append(ptabs, n)
|
||||
}
|
||||
}
|
||||
|
||||
// NeedEmit reports whether typ is a type that we need to emit code
|
||||
// for (e.g., runtime type descriptors, method wrappers).
|
||||
func NeedEmit(typ *types.Type) bool {
|
||||
|
@ -681,9 +681,15 @@ var statuniqgen int // name generator for static temps
|
||||
// Use readonlystaticname for read-only node.
|
||||
func StaticName(t *types.Type) *ir.Name {
|
||||
// Don't use LookupNum; it interns the resulting string, but these are all unique.
|
||||
n := typecheck.NewName(typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen)))
|
||||
sym := typecheck.Lookup(fmt.Sprintf("%s%d", obj.StaticNamePref, statuniqgen))
|
||||
statuniqgen++
|
||||
typecheck.Declare(n, ir.PEXTERN)
|
||||
|
||||
n := typecheck.NewName(sym)
|
||||
sym.Def = n
|
||||
|
||||
n.Class = ir.PEXTERN
|
||||
typecheck.Target.Externs = append(typecheck.Target.Externs, n)
|
||||
|
||||
n.SetType(t)
|
||||
n.Linksym().Set(obj.AttrStatic, true)
|
||||
return n
|
||||
|
@ -27,10 +27,10 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F
|
||||
|
||||
var recv1 *types.Field
|
||||
if recv != nil {
|
||||
recv1 = declareParam(ir.PPARAM, -1, recv)
|
||||
recv1 = declareParam(fn, ir.PPARAM, -1, recv)
|
||||
}
|
||||
|
||||
typ := types.NewSignature(recv1, declareParams(ir.PPARAM, params), declareParams(ir.PPARAMOUT, results))
|
||||
typ := types.NewSignature(recv1, declareParams(fn, ir.PPARAM, params), declareParams(fn, ir.PPARAMOUT, results))
|
||||
checkdupfields("argument", typ.Recvs().FieldSlice(), typ.Params().FieldSlice(), typ.Results().FieldSlice())
|
||||
fn.Nname.SetType(typ)
|
||||
fn.Nname.SetTypecheck(1)
|
||||
@ -38,66 +38,6 @@ func DeclFunc(sym *types.Sym, recv *ir.Field, params, results []*ir.Field) *ir.F
|
||||
return fn
|
||||
}
|
||||
|
||||
// Declare records that Node n declares symbol n.Sym in the specified
|
||||
// declaration context.
|
||||
func Declare(n *ir.Name, ctxt ir.Class) {
|
||||
if ir.IsBlank(n) {
|
||||
return
|
||||
}
|
||||
|
||||
s := n.Sym()
|
||||
|
||||
// kludgy: TypecheckAllowed means we're past parsing. Eg reflectdata.methodWrapper may declare out of package names later.
|
||||
if !inimport && !TypecheckAllowed && s.Pkg != types.LocalPkg {
|
||||
base.ErrorfAt(n.Pos(), 0, "cannot declare name %v", s)
|
||||
}
|
||||
|
||||
if ctxt == ir.PEXTERN {
|
||||
if s.Name == "init" {
|
||||
base.ErrorfAt(n.Pos(), errors.InvalidInitDecl, "cannot declare init - must be func")
|
||||
}
|
||||
if s.Name == "main" && s.Pkg.Name == "main" {
|
||||
base.ErrorfAt(n.Pos(), errors.InvalidMainDecl, "cannot declare main - must be func")
|
||||
}
|
||||
Target.Externs = append(Target.Externs, n)
|
||||
s.Def = n
|
||||
} else {
|
||||
if ir.CurFunc == nil && ctxt == ir.PAUTO {
|
||||
base.Pos = n.Pos()
|
||||
base.Fatalf("automatic outside function")
|
||||
}
|
||||
if ir.CurFunc != nil && ctxt != ir.PFUNC && n.Op() == ir.ONAME {
|
||||
ir.CurFunc.Dcl = append(ir.CurFunc.Dcl, n)
|
||||
}
|
||||
n.Curfn = ir.CurFunc
|
||||
}
|
||||
|
||||
if ctxt == ir.PAUTO {
|
||||
n.SetFrameOffset(0)
|
||||
}
|
||||
|
||||
n.Class = ctxt
|
||||
if ctxt == ir.PFUNC {
|
||||
n.Sym().SetFunc(true)
|
||||
}
|
||||
|
||||
autoexport(n, ctxt)
|
||||
}
|
||||
|
||||
// Export marks n for export (or reexport).
|
||||
func Export(n *ir.Name) {
|
||||
if n.Sym().OnExportList() {
|
||||
return
|
||||
}
|
||||
n.Sym().SetOnExportList(true)
|
||||
|
||||
if base.Flag.E != 0 {
|
||||
fmt.Printf("export symbol %v\n", n.Sym())
|
||||
}
|
||||
|
||||
Target.Exports = append(Target.Exports, n)
|
||||
}
|
||||
|
||||
// declare the function proper
|
||||
// and declare the arguments.
|
||||
// called in extern-declaration context
|
||||
@ -125,26 +65,6 @@ func CheckFuncStack() {
|
||||
}
|
||||
}
|
||||
|
||||
func autoexport(n *ir.Name, ctxt ir.Class) {
|
||||
if n.Sym().Pkg != types.LocalPkg {
|
||||
return
|
||||
}
|
||||
if (ctxt != ir.PEXTERN && ctxt != ir.PFUNC) || DeclContext != ir.PEXTERN {
|
||||
return
|
||||
}
|
||||
if n.Type() != nil && n.Type().IsKind(types.TFUNC) && ir.IsMethod(n) {
|
||||
return
|
||||
}
|
||||
|
||||
if types.IsExported(n.Sym().Name) || n.Sym().Name == "init" {
|
||||
Export(n)
|
||||
}
|
||||
if base.Flag.AsmHdr != "" && !n.Sym().Asm() {
|
||||
n.Sym().SetAsm(true)
|
||||
Target.Asms = append(Target.Asms, n)
|
||||
}
|
||||
}
|
||||
|
||||
// checkdupfields emits errors for duplicately named fields or methods in
|
||||
// a list of struct or interface types.
|
||||
func checkdupfields(what string, fss ...[]*types.Field) {
|
||||
@ -170,15 +90,15 @@ type funcStackEnt struct {
|
||||
dclcontext ir.Class
|
||||
}
|
||||
|
||||
func declareParams(ctxt ir.Class, l []*ir.Field) []*types.Field {
|
||||
func declareParams(fn *ir.Func, ctxt ir.Class, l []*ir.Field) []*types.Field {
|
||||
fields := make([]*types.Field, len(l))
|
||||
for i, n := range l {
|
||||
fields[i] = declareParam(ctxt, i, n)
|
||||
fields[i] = declareParam(fn, ctxt, i, n)
|
||||
}
|
||||
return fields
|
||||
}
|
||||
|
||||
func declareParam(ctxt ir.Class, i int, param *ir.Field) *types.Field {
|
||||
func declareParam(fn *ir.Func, ctxt ir.Class, i int, param *ir.Field) *types.Field {
|
||||
f := types.NewField(param.Pos, param.Sym, param.Type)
|
||||
f.SetIsDDD(param.IsDDD)
|
||||
|
||||
@ -202,7 +122,10 @@ func declareParam(ctxt ir.Class, i int, param *ir.Field) *types.Field {
|
||||
name := ir.NewNameAt(param.Pos, sym)
|
||||
name.SetType(f.Type)
|
||||
name.SetTypecheck(1)
|
||||
Declare(name, ctxt)
|
||||
|
||||
name.Class = ctxt
|
||||
fn.Dcl = append(fn.Dcl, name)
|
||||
name.Curfn = fn
|
||||
|
||||
f.Nname = name
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user