]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: remove global var importpkg in favor of simple bool
authorRobert Griesemer <gri@golang.org>
Fri, 24 Mar 2017 00:39:28 +0000 (17:39 -0700)
committerRobert Griesemer <gri@golang.org>
Fri, 24 Mar 2017 00:53:45 +0000 (00:53 +0000)
Pass around the imported package explicitly instead of relying
on a global variable.

Unfortunately we still need a global variable to communicate to
the typechecker that we're in an import, but the semantic load
is significantly reduced as it's just a bool, set/reset in a
couple of places only.

Change-Id: I4ebeae4064eb76ca0c4e2a15e4ca53813f005c29
Reviewed-on: https://go-review.googlesource.com/38595
Run-TryBot: Robert Griesemer <gri@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>

src/cmd/compile/internal/gc/bimport.go
src/cmd/compile/internal/gc/dcl.go
src/cmd/compile/internal/gc/export.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/gc/subr.go
src/cmd/compile/internal/gc/typecheck.go

index 9ee56ec784a37377bd7698b4532a24bf68d2caa7..fd87ddd8570df143f413f714b5d9f515c3d52432 100644 (file)
@@ -50,8 +50,11 @@ type importer struct {
        read        int // bytes read
 }
 
-// Import populates imp from the serialized package data.
-func Import(in *bufio.Reader, imp *Pkg) {
+// Import populates imp from the serialized package data read from in.
+func Import(imp *Pkg, in *bufio.Reader) {
+       inimport = true
+       defer func() { inimport = false }()
+
        p := importer{
                in:      in,
                imp:     imp,
@@ -319,13 +322,13 @@ func (p *importer) obj(tag int) {
                sym := p.qualifiedName()
                typ := p.typ()
                val := p.value(typ)
-               importconst(sym, idealType(typ), nodlit(val))
+               importconst(p.imp, sym, idealType(typ), nodlit(val))
 
        case aliasTag:
                p.pos()
                sym := p.qualifiedName()
                typ := p.typ()
-               importalias(sym, typ)
+               importalias(p.imp, sym, typ)
 
        case typeTag:
                p.typ()
@@ -334,7 +337,7 @@ func (p *importer) obj(tag int) {
                p.pos()
                sym := p.qualifiedName()
                typ := p.typ()
-               importvar(sym, typ)
+               importvar(p.imp, sym, typ)
 
        case funcTag:
                p.pos()
@@ -343,7 +346,7 @@ func (p *importer) obj(tag int) {
                result := p.paramList()
 
                sig := functypefield(nil, params, result)
-               importsym(sym, ONAME)
+               importsym(p.imp, sym, ONAME)
                if sym.Def != nil && sym.Def.Op == ONAME {
                        // function was imported before (via another import)
                        if !eqtype(sig, sym.Def.Type) {
@@ -441,7 +444,7 @@ func (p *importer) typ() *Type {
                p.pos()
                tsym := p.qualifiedName()
 
-               t = pkgtype(tsym)
+               t = pkgtype(p.imp, tsym)
                p.typList = append(p.typList, t)
 
                // read underlying type
index 21a2b213259a17e5a3be417b51a0a9c6c72bef38..77c6759fbb7ffb6552fec7a5342aae762cf6abeb 100644 (file)
@@ -165,7 +165,7 @@ func declare(n *Node, ctxt Class) {
        s := n.Sym
 
        // kludgy: typecheckok means we're past parsing. Eg genwrapper may declare out of package names later.
-       if importpkg == nil && !typecheckok && s.Pkg != localpkg {
+       if !inimport && !typecheckok && s.Pkg != localpkg {
                yyerror("cannot declare name %v", s)
        }
 
index 15def93ef5be5647df61ee5479ed36abf2ba8549..10e21838f5521e3635f4a71c7fb6d0968c86c6d9 100644 (file)
@@ -176,9 +176,7 @@ func dumpexport() {
                savedPkgs := pkgs
                pkgMap = make(map[string]*Pkg)
                pkgs = nil
-               importpkg = mkpkg("")
-               Import(bufio.NewReader(&copy), importpkg) // must not die
-               importpkg = nil
+               Import(mkpkg(""), bufio.NewReader(&copy)) // must not die
                pkgs = savedPkgs
                pkgMap = savedPkgMap
        } else {
@@ -192,9 +190,10 @@ func dumpexport() {
 }
 
 // importsym declares symbol s as an imported object representable by op.
-func importsym(s *Sym, op Op) {
+// pkg is the package being imported
+func importsym(pkg *Pkg, s *Sym, op Op) {
        if s.Def != nil && s.Def.Op != op {
-               pkgstr := fmt.Sprintf("during import %q", importpkg.Path)
+               pkgstr := fmt.Sprintf("during import %q", pkg.Path)
                redeclare(s, pkgstr)
        }
 
@@ -210,8 +209,9 @@ func importsym(s *Sym, op Op) {
 
 // pkgtype returns the named type declared by symbol s.
 // If no such type has been declared yet, a forward declaration is returned.
-func pkgtype(s *Sym) *Type {
-       importsym(s, OTYPE)
+// pkg is the package being imported
+func pkgtype(pkg *Pkg, s *Sym) *Type {
+       importsym(pkg, s, OTYPE)
        if s.Def == nil || s.Def.Op != OTYPE {
                t := typ(TFORW)
                t.Sym = s
@@ -226,8 +226,9 @@ func pkgtype(s *Sym) *Type {
 }
 
 // importconst declares symbol s as an imported constant with type t and value n.
-func importconst(s *Sym, t *Type, n *Node) {
-       importsym(s, OLITERAL)
+// pkg is the package being imported
+func importconst(pkg *Pkg, s *Sym, t *Type, n *Node) {
+       importsym(pkg, s, OLITERAL)
        n = convlit(n, t)
 
        if s.Def != nil { // TODO: check if already the same.
@@ -254,17 +255,18 @@ func importconst(s *Sym, t *Type, n *Node) {
 }
 
 // importvar declares symbol s as an imported variable with type t.
-func importvar(s *Sym, t *Type) {
-       importsym(s, ONAME)
+// pkg is the package being imported
+func importvar(pkg *Pkg, s *Sym, t *Type) {
+       importsym(pkg, s, ONAME)
        if s.Def != nil && s.Def.Op == ONAME {
                if eqtype(t, s.Def.Type) {
                        return
                }
-               yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, importpkg.Path)
+               yyerror("inconsistent definition for var %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, pkg.Path)
        }
 
        n := newname(s)
-       s.Importdef = importpkg
+       s.Importdef = pkg
        n.Type = t
        declare(n, PEXTERN)
 
@@ -274,18 +276,19 @@ func importvar(s *Sym, t *Type) {
 }
 
 // importalias declares symbol s as an imported type alias with type t.
-func importalias(s *Sym, t *Type) {
-       importsym(s, OTYPE)
+// pkg is the package being imported
+func importalias(pkg *Pkg, s *Sym, t *Type) {
+       importsym(pkg, s, OTYPE)
        if s.Def != nil && s.Def.Op == OTYPE {
                if eqtype(t, s.Def.Type) {
                        return
                }
-               yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, importpkg.Path)
+               yyerror("inconsistent definition for type alias %v during import\n\t%v (in %q)\n\t%v (in %q)", s, s.Def.Type, s.Importdef.Path, t, pkg.Path)
        }
 
        n := newname(s)
        n.Op = OTYPE
-       s.Importdef = importpkg
+       s.Importdef = pkg
        n.Type = t
        declare(n, PEXTERN)
 
index 2c83d7689c059a4b863198cb7c8d560dd191d425..12076fc94a6dc2655aeac9aafe7e6b63a85e01ef 100644 (file)
@@ -168,7 +168,7 @@ var Debug_typeassert int
 
 var localpkg *Pkg // package being compiled
 
-var importpkg *Pkg // package being imported
+var inimport bool // set during import
 
 var itabpkg *Pkg // fake pkg for itab entries
 
index 2ceb8d4bbbc1050853fc9293f80244d1da0998e4..884790da1eed0ea09366f5d991a6f69e0626ef04 100644 (file)
@@ -719,22 +719,22 @@ func findpkg(name string) (file string, ok bool) {
 func loadsys() {
        block = 1
 
-       importpkg = Runtimepkg
+       inimport = true
        typecheckok = true
        defercheckwidth()
 
        typs := runtimeTypes()
        for _, d := range runtimeDecls {
-               sym := Pkglookup(d.name, importpkg)
+               sym := Pkglookup(d.name, Runtimepkg)
                typ := typs[d.typ]
                switch d.tag {
                case funcTag:
-                       importsym(sym, ONAME)
+                       importsym(Runtimepkg, sym, ONAME)
                        n := newfuncname(sym)
                        n.Type = typ
                        declare(n, PFUNC)
                case varTag:
-                       importvar(sym, typ)
+                       importvar(Runtimepkg, sym, typ)
                default:
                        Fatalf("unhandled declaration tag %v", d.tag)
                }
@@ -742,27 +742,23 @@ func loadsys() {
 
        typecheckok = false
        resumecheckwidth()
-       importpkg = nil
+       inimport = false
 }
 
-func importfile(f *Val, indent []byte) {
-       if importpkg != nil {
-               Fatalf("importpkg not nil")
-       }
-
+func importfile(f *Val, indent []byte) *Pkg {
        path_, ok := f.U.(string)
        if !ok {
                yyerror("import statement not a string")
-               return
+               return nil
        }
 
        if len(path_) == 0 {
                yyerror("import path is empty")
-               return
+               return nil
        }
 
        if isbadimport(path_) {
-               return
+               return nil
        }
 
        // The package name main is no longer reserved,
@@ -789,15 +785,14 @@ func importfile(f *Val, indent []byte) {
                        errorexit()
                }
 
-               importpkg = unsafepkg
                imported_unsafe = true
-               return
+               return unsafepkg
        }
 
        if islocalname(path_) {
                if path_[0] == '/' {
                        yyerror("import path cannot be absolute path")
-                       return
+                       return nil
                }
 
                prefix := Ctxt.Pathname
@@ -807,7 +802,7 @@ func importfile(f *Val, indent []byte) {
                path_ = path.Join(prefix, path_)
 
                if isbadimport(path_) {
-                       return
+                       return nil
                }
        }
 
@@ -817,10 +812,9 @@ func importfile(f *Val, indent []byte) {
                errorexit()
        }
 
-       importpkg = mkpkg(path_)
-
+       importpkg := mkpkg(path_)
        if importpkg.Imported {
-               return
+               return importpkg
        }
 
        importpkg.Imported = true
@@ -913,18 +907,21 @@ func importfile(f *Val, indent []byte) {
        switch c {
        case '\n':
                yyerror("cannot import %s: old export format no longer supported (recompile library)", path_)
+               return nil
 
        case 'B':
                if Debug_export != 0 {
                        fmt.Printf("importing %s (%s)\n", path_, file)
                }
                imp.ReadByte() // skip \n after $$B
-               Import(imp, importpkg)
+               Import(importpkg, imp)
 
        default:
                yyerror("no import in %q", path_)
                errorexit()
        }
+
+       return importpkg
 }
 
 func pkgnotused(lineno src.XPos, path string, name string) {
index 0bddd6af394c8631f98d463f2f866cb10b5b8472..8b38606d334c1eb58140aaf0978732b2d5530079 100644 (file)
@@ -136,9 +136,7 @@ func (p *noder) decls(decls []syntax.Decl) (l []*Node) {
 
 func (p *noder) importDecl(imp *syntax.ImportDecl) {
        val := p.basicLit(imp.Path)
-       importfile(&val, nil)
-       ipkg := importpkg
-       importpkg = nil
+       ipkg := importfile(&val, nil)
 
        if ipkg == nil {
                if nerrors == 0 {
index 6b18cd2f6ef9a9bba38045ec9a49d0ad037fee48..d486bd97755fe2a7c31a3b5f4c41cac52cd15efa 100644 (file)
@@ -718,7 +718,7 @@ func assignop(src *Type, dst *Type, why *string) Op {
 
        // TODO(rsc,lvd): This behaves poorly in the presence of inlining.
        // https://golang.org/issue/2795
-       if safemode && importpkg == nil && src != nil && src.Etype == TUNSAFEPTR {
+       if safemode && !inimport && src != nil && src.Etype == TUNSAFEPTR {
                yyerror("cannot use unsafe.Pointer")
                errorexit()
        }
index 353380a0d9d12f29fd5a32fb37e086d994a0dda3..00045930ebc5504967b2759f24c6eee69b6e7574 100644 (file)
@@ -2143,7 +2143,7 @@ OpSwitch:
                }
        }
 
-       if safemode && importpkg == nil && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
+       if safemode && !inimport && compiling_wrappers == 0 && t != nil && t.Etype == TUNSAFEPTR {
                yyerror("cannot use unsafe.Pointer")
        }
 
@@ -3472,7 +3472,7 @@ func typecheckfunc(n *Node) {
                addmethod(n.Func.Shortname, t, true, n.Func.Pragma&Nointerface != 0)
        }
 
-       if Ctxt.Flag_dynlink && importpkg == nil && n.Func.Nname != nil {
+       if Ctxt.Flag_dynlink && !inimport && n.Func.Nname != nil {
                makefuncsym(n.Func.Nname.Sym)
        }
 }