]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: separate noder more cleanly
authorRuss Cox <rsc@golang.org>
Mon, 21 Dec 2020 06:36:15 +0000 (01:36 -0500)
committerRuss Cox <rsc@golang.org>
Mon, 21 Dec 2020 19:23:30 +0000 (19:23 +0000)
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>
src/cmd/compile/internal/gc/embed.go
src/cmd/compile/internal/gc/go.go
src/cmd/compile/internal/gc/main.go
src/cmd/compile/internal/gc/noder.go
src/cmd/compile/internal/ir/name.go
src/embed/internal/embedtest/embed_test.go
src/embed/internal/embedtest/embedx_test.go

index 7d67d2dfd01babf1b3f88f7fb9c79d75fcdc6a5b..0d4ce83716458e90c135a0a7d7670f78dfbd918f 100644 (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
        }
+       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
+}
 
-       kind := embedKindApprox(typ)
+func embedFileList(v *ir.Name) []string {
+       kind := embedKind(v.Type())
        if kind == embedUnknown {
-               p.errorAt(pos, "go:embed cannot apply to var of type %v", typ)
-               return exprs
+               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())
index b092e6933c825a49c068dead496e62a9739729f6..1707e6a11b86221e30b82988bfe253bf7ee44ffa 100644 (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
index 545491daa1a671d4af3ce40221e9f4b79134eb1b..45880c5cde5dd3e2e72b41b562d6b8847efa2940 100644 (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
index 10eac6e815b586944eb2b528ee986a9c6b13fa51..ee01423833cb5102373190df730a6ff257071b25 100644 (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...)
 }
 
index 0c36ffdf7a38710c668dfcc428884c49485aa587..f5f4280fd079e9741e3635779616a501afbb5c2a 100644 (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
index c6a7bea7a33125419b5d59cc46e7b3de8fc51a97..04c23172c284078098ee922eeb6e25fcbe78ef65 100644 (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/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 dir embed.FS
 
-func TestDir(t *testing.T) {
-       //go:embed testdata
-       var all embed.FS
+//go:embed testdata/*
+var star embed.FS
 
+func TestDir(t *testing.T) {
+       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",
index 20d5a28c11df82e7c5ae440cebeb1584581ccac2..27fa11614e9268ea19149cb5c4cabd9faa374407 100644 (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")
-}