1
0
mirror of https://github.com/golang/go synced 2024-11-23 00:50:05 -07:00

[dev.regabi] cmd/compile: separate noder more cleanly

Separate embed, cgo pragmas, and Main trackScopes variable
from noder more cleanly.

This lets us split embed and noder into new packages.
It also assumes that the local embedded variables will be
removed and deletes them now for simplicity.

Change-Id: I9638bcc2c5f0e76440de056c6285b6aa2f73a00d
Reviewed-on: https://go-review.googlesource.com/c/go/+/279299
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-12-21 01:36:15 -05:00
parent 85ce6ecfe3
commit 4836e28ac0
7 changed files with 72 additions and 120 deletions

View File

@ -24,8 +24,6 @@ const (
embedFiles
)
var numLocalEmbed int
func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) {
haveEmbed := false
for _, decl := range p.file.DeclList {
@ -63,25 +61,39 @@ func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds [
p.errorAt(pos, "go:embed cannot apply to var without type")
return exprs
}
kind := embedKindApprox(typ)
if kind == embedUnknown {
p.errorAt(pos, "go:embed cannot apply to var of type %v", typ)
if dclcontext != ir.PEXTERN {
p.errorAt(pos, "go:embed cannot apply to var inside func")
return exprs
}
v := names[0].(*ir.Name)
Target.Embeds = append(Target.Embeds, v)
v.Embed = new([]ir.Embed)
for _, e := range embeds {
*v.Embed = append(*v.Embed, ir.Embed{Pos: p.makeXPos(e.Pos), Patterns: e.Patterns})
}
return exprs
}
func embedFileList(v *ir.Name) []string {
kind := embedKind(v.Type())
if kind == embedUnknown {
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())
return nil
}
// Build list of files to store.
have := make(map[string]bool)
var list []string
for _, e := range embeds {
for _, e := range *v.Embed {
for _, pattern := range e.Patterns {
files, ok := base.Flag.Cfg.Embed.Patterns[pattern]
if !ok {
p.errorAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern)
}
for _, file := range files {
if base.Flag.Cfg.Embed.Files[file] == "" {
p.errorAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
base.ErrorfAt(e.Pos, "invalid go:embed: build system did not map file: %s", file)
continue
}
if !have[file] {
@ -103,25 +115,12 @@ func varEmbed(p *noder, names []ir.Node, typ ir.Ntype, exprs []ir.Node, embeds [
if kind == embedString || kind == embedBytes {
if len(list) > 1 {
p.errorAt(pos, "invalid go:embed: multiple files for type %v", typ)
return exprs
base.ErrorfAt(v.Pos(), "invalid go:embed: multiple files for type %v", v.Type())
return nil
}
}
v := names[0].(*ir.Name)
if dclcontext != ir.PEXTERN {
numLocalEmbed++
v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed))
v.Sym().Def = v
v.Name().Ntype = typ
v.SetClass(ir.PEXTERN)
Target.Externs = append(Target.Externs, v)
exprs = []ir.Node{v}
}
v.Name().SetEmbedFiles(list)
Target.Embeds = append(Target.Embeds, v)
return exprs
return list
}
// embedKindApprox determines the kind of embedding variable, approximately.
@ -192,8 +191,8 @@ func dumpembeds() {
// initEmbed emits the init data for a //go:embed variable,
// which is either a string, a []byte, or an embed.FS.
func initEmbed(v ir.Node) {
files := v.Name().EmbedFiles()
func initEmbed(v *ir.Name) {
files := embedFileList(v)
switch kind := embedKind(v.Type()); kind {
case embedUnknown:
base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type())

View File

@ -116,13 +116,14 @@ var (
okforadd [types.NTYPE]bool
okforand [types.NTYPE]bool
okfornone [types.NTYPE]bool
okforcmp [types.NTYPE]bool
okforbool [types.NTYPE]bool
okforcap [types.NTYPE]bool
okforlen [types.NTYPE]bool
okforarith [types.NTYPE]bool
)
var okforcmp [types.NTYPE]bool
var (
okfor [ir.OEND][]bool
iscmp [ir.OEND]bool
@ -149,9 +150,6 @@ var typecheckok bool
// when the race detector is enabled.
var instrumenting bool
// Whether we are tracking lexical scopes for DWARF.
var trackScopes bool
var nodfp *ir.Name
var autogeneratedPos src.XPos

View File

@ -205,8 +205,6 @@ func Main(archInit func(*Arch)) {
}
}
trackScopes = base.Flag.Dwarf
Widthptr = thearch.LinkArch.PtrSize
Widthreg = thearch.LinkArch.RegSize
@ -226,6 +224,7 @@ func Main(archInit func(*Arch)) {
timings.Start("fe", "parse")
lines := parseFiles(flag.Args())
cgoSymABIs()
timings.Stop()
timings.AddEvent(int64(lines), "lines")
@ -477,6 +476,20 @@ func Main(archInit func(*Arch)) {
}
}
func cgoSymABIs() {
// The linker expects an ABI0 wrapper for all cgo-exported
// functions.
for _, prag := range Target.CgoPragmas {
switch prag[0] {
case "cgo_export_static", "cgo_export_dynamic":
if symabiRefs == nil {
symabiRefs = make(map[string]obj.ABI)
}
symabiRefs[prag[1]] = obj.ABI0
}
}
}
// numNonClosures returns the number of functions in list which are not closures.
func numNonClosures(list []*ir.Func) int {
count := 0

View File

@ -20,7 +20,6 @@ import (
"cmd/compile/internal/ir"
"cmd/compile/internal/syntax"
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/objabi"
"cmd/internal/src"
)
@ -36,8 +35,9 @@ func parseFiles(filenames []string) uint {
for _, filename := range filenames {
p := &noder{
basemap: make(map[*syntax.PosBase]*src.PosBase),
err: make(chan syntax.Error),
basemap: make(map[*syntax.PosBase]*src.PosBase),
err: make(chan syntax.Error),
trackScopes: base.Flag.Dwarf,
}
noders = append(noders, p)
@ -151,7 +151,8 @@ type noder struct {
// scopeVars is a stack tracking the number of variables declared in the
// current function at the moment each open scope was opened.
scopeVars []int
trackScopes bool
scopeVars []int
lastCloseScopePos syntax.Pos
}
@ -179,7 +180,7 @@ func (p *noder) funcBody(fn *ir.Func, block *syntax.BlockStmt) {
func (p *noder) openScope(pos syntax.Pos) {
types.Markdcl()
if trackScopes {
if p.trackScopes {
Curfn.Parents = append(Curfn.Parents, p.scope)
p.scopeVars = append(p.scopeVars, len(Curfn.Dcl))
p.scope = ir.ScopeID(len(Curfn.Parents))
@ -192,7 +193,7 @@ func (p *noder) closeScope(pos syntax.Pos) {
p.lastCloseScopePos = pos
types.Popdcl()
if trackScopes {
if p.trackScopes {
scopeVars := p.scopeVars[len(p.scopeVars)-1]
p.scopeVars = p.scopeVars[:len(p.scopeVars)-1]
if scopeVars == len(Curfn.Dcl) {
@ -284,19 +285,6 @@ func (p *noder) processPragmas() {
}
n.Sym().Linkname = l.remote
}
// The linker expects an ABI0 wrapper for all cgo-exported
// functions.
for _, prag := range p.pragcgobuf {
switch prag[0] {
case "cgo_export_static", "cgo_export_dynamic":
if symabiRefs == nil {
symabiRefs = make(map[string]obj.ABI)
}
symabiRefs[prag[1]] = obj.ABI0
}
}
Target.CgoPragmas = append(Target.CgoPragmas, p.pragcgobuf...)
}

View File

@ -34,16 +34,16 @@ func (*Ident) CanBeNtype() {}
// Name holds Node fields used only by named nodes (ONAME, OTYPE, some OLITERAL).
type Name struct {
miniExpr
BuiltinOp Op // uint8
Class_ Class // uint8
flags bitset16
pragma PragmaFlag // int16
sym *types.Sym
fn *Func
Offset_ int64
val constant.Value
orig Node
embedFiles *[]string // list of embedded files, for ONAME var
BuiltinOp Op // uint8
Class_ Class // uint8
flags bitset16
pragma PragmaFlag // int16
sym *types.Sym
fn *Func
Offset_ int64
val constant.Value
orig Node
Embed *[]Embed // list of embedded files, for ONAME var
PkgName *PkgName // real package for import . names
// For a local variable (not param) or extern, the initializing assignment (OAS or OAS2).
@ -139,14 +139,14 @@ type Name struct {
Outer *Name
}
func (n *Name) isExpr() {}
// CloneName makes a cloned copy of the name.
// It's not ir.Copy(n) because in general that operation is a mistake on names,
// which uniquely identify variables.
// Callers must use n.CloneName to make clear they intend to create a separate name.
func (n *Name) CloneName() *Name { c := *n; return &c }
func (n *Name) isExpr() {}
// NewNameAt returns a new ONAME Node associated with symbol s at position pos.
// The caller is responsible for setting Curfn.
func NewNameAt(pos src.XPos, sym *types.Sym) *Name {
@ -231,27 +231,6 @@ func (n *Name) Alias() bool { return n.flags&nameAlias != 0 }
// SetAlias sets whether p, which must be for an OTYPE, is a type alias.
func (n *Name) SetAlias(alias bool) { n.flags.set(nameAlias, alias) }
// EmbedFiles returns the list of embedded files for p,
// which must be for an ONAME var.
func (n *Name) EmbedFiles() []string {
if n.embedFiles == nil {
return nil
}
return *n.embedFiles
}
// SetEmbedFiles sets the list of embedded files for p,
// which must be for an ONAME var.
func (n *Name) SetEmbedFiles(list []string) {
if n.embedFiles == nil && list == nil {
return
}
if n.embedFiles == nil {
n.embedFiles = new([]string)
}
*n.embedFiles = list
}
const (
nameCaptured = 1 << iota // is the variable captured by a closure
nameReadonly
@ -389,6 +368,11 @@ const (
_ = uint((1 << 3) - iota) // static assert for iota <= (1 << 3)
)
type Embed struct {
Pos src.XPos
Patterns []string
}
// A Pack is an identifier referring to an imported package.
type PkgName struct {
miniNode

View File

@ -73,24 +73,14 @@ func TestGlobal(t *testing.T) {
testString(t, string(glass), "glass", "I can eat glass and it doesn't hurt me.\n")
}
func TestLocal(t *testing.T) {
//go:embed testdata/k*.txt
var local embed.FS
testFiles(t, local, "testdata/ken.txt", "If a program is too slow, it must have a loop.\n")
//go:embed testdata
var dir embed.FS
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
}
//go:embed testdata/*
var star embed.FS
func TestDir(t *testing.T) {
//go:embed testdata
var all embed.FS
all := dir
testFiles(t, all, "testdata/hello.txt", "hello, world\n")
testFiles(t, all, "testdata/i/i18n.txt", "internationalization\n")
testFiles(t, all, "testdata/i/j/k/k8s.txt", "kubernetes\n")
@ -103,12 +93,6 @@ func TestDir(t *testing.T) {
}
func TestHidden(t *testing.T) {
//go:embed testdata
var dir embed.FS
//go:embed testdata/*
var star embed.FS
t.Logf("//go:embed testdata")
testDir(t, dir, "testdata",

View File

@ -90,17 +90,3 @@ func TestXGlobal(t *testing.T) {
}
bbig[0] = old
}
func TestXLocal(t *testing.T) {
//go:embed testdata/*o.txt
var local embed.FS
testFiles(t, local, "testdata/hello.txt", "hello, world\n")
//go:embed testdata/k*.txt
var s string
testString(t, s, "local variable s", "If a program is too slow, it must have a loop.\n")
//go:embed testdata/h*.txt
var b []byte
testString(t, string(b), "local variable b", "hello, world\n")
}