diff options
Diffstat (limited to 'src/cmd/compile/internal/gc/embed.go')
-rw-r--r-- | src/cmd/compile/internal/gc/embed.go | 107 |
1 files changed, 43 insertions, 64 deletions
diff --git a/src/cmd/compile/internal/gc/embed.go b/src/cmd/compile/internal/gc/embed.go index 103949c1f9..33b05a5bf0 100644 --- a/src/cmd/compile/internal/gc/embed.go +++ b/src/cmd/compile/internal/gc/embed.go @@ -5,40 +5,19 @@ package gc import ( + "cmd/compile/internal/base" + "cmd/compile/internal/ir" "cmd/compile/internal/syntax" "cmd/compile/internal/types" "cmd/internal/obj" - "encoding/json" - "io/ioutil" - "log" + "path" "sort" "strconv" "strings" ) -var embedlist []*Node - -var embedCfg struct { - Patterns map[string][]string - Files map[string]string -} - -func readEmbedCfg(file string) { - data, err := ioutil.ReadFile(file) - if err != nil { - log.Fatalf("-embedcfg: %v", err) - } - if err := json.Unmarshal(data, &embedCfg); err != nil { - log.Fatalf("%s: %v", file, err) - } - if embedCfg.Patterns == nil { - log.Fatalf("%s: invalid embedcfg: missing Patterns", file) - } - if embedCfg.Files == nil { - log.Fatalf("%s: invalid embedcfg: missing Files", file) - } -} +var embedlist []ir.Node const ( embedUnknown = iota @@ -49,7 +28,7 @@ const ( var numLocalEmbed int -func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []PragmaEmbed) (newExprs []*Node) { +func varEmbed(p *noder, names []ir.Node, typ ir.Node, exprs []ir.Node, embeds []PragmaEmbed) (newExprs []ir.Node) { haveEmbed := false for _, decl := range p.file.DeclList { imp, ok := decl.(*syntax.ImportDecl) @@ -66,30 +45,30 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma pos := embeds[0].Pos if !haveEmbed { - p.yyerrorpos(pos, "invalid go:embed: missing import \"embed\"") + p.errorAt(pos, "invalid go:embed: missing import \"embed\"") return exprs } - if embedCfg.Patterns == nil { - p.yyerrorpos(pos, "invalid go:embed: build system did not supply embed configuration") + if base.Flag.Cfg.Embed.Patterns == nil { + p.errorAt(pos, "invalid go:embed: build system did not supply embed configuration") return exprs } if len(names) > 1 { - p.yyerrorpos(pos, "go:embed cannot apply to multiple vars") + p.errorAt(pos, "go:embed cannot apply to multiple vars") return exprs } if len(exprs) > 0 { - p.yyerrorpos(pos, "go:embed cannot apply to var with initializer") + p.errorAt(pos, "go:embed cannot apply to var with initializer") return exprs } if typ == nil { // Should not happen, since len(exprs) == 0 now. - p.yyerrorpos(pos, "go:embed cannot apply to var without type") + p.errorAt(pos, "go:embed cannot apply to var without type") return exprs } kind := embedKindApprox(typ) if kind == embedUnknown { - p.yyerrorpos(pos, "go:embed cannot apply to var of type %v", typ) + p.errorAt(pos, "go:embed cannot apply to var of type %v", typ) return exprs } @@ -98,13 +77,13 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma var list []string for _, e := range embeds { for _, pattern := range e.Patterns { - files, ok := embedCfg.Patterns[pattern] + files, ok := base.Flag.Cfg.Embed.Patterns[pattern] if !ok { - p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern) + p.errorAt(e.Pos, "invalid go:embed: build system did not map pattern: %s", pattern) } for _, file := range files { - if embedCfg.Files[file] == "" { - p.yyerrorpos(e.Pos, "invalid go:embed: build system did not map file: %s", file) + if base.Flag.Cfg.Embed.Files[file] == "" { + p.errorAt(e.Pos, "invalid go:embed: build system did not map file: %s", file) continue } if !have[file] { @@ -126,23 +105,23 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma if kind == embedString || kind == embedBytes { if len(list) > 1 { - p.yyerrorpos(pos, "invalid go:embed: multiple files for type %v", typ) + p.errorAt(pos, "invalid go:embed: multiple files for type %v", typ) return exprs } } v := names[0] - if dclcontext != PEXTERN { + if dclcontext != ir.PEXTERN { numLocalEmbed++ - v = newnamel(v.Pos, lookupN("embed.", numLocalEmbed)) - v.Sym.Def = asTypesNode(v) - v.Name.Param.Ntype = typ - v.SetClass(PEXTERN) + v = ir.NewNameAt(v.Pos(), lookupN("embed.", numLocalEmbed)) + v.Sym().Def = v + v.Name().Param.Ntype = typ + v.SetClass(ir.PEXTERN) externdcl = append(externdcl, v) - exprs = []*Node{v} + exprs = []ir.Node{v} } - v.Name.Param.SetEmbedFiles(list) + v.Name().Param.SetEmbedFiles(list) embedlist = append(embedlist, v) return exprs } @@ -151,18 +130,18 @@ func varEmbed(p *noder, names []*Node, typ *Node, exprs []*Node, embeds []Pragma // The match is approximate because we haven't done scope resolution yet and // can't tell whether "string" and "byte" really mean "string" and "byte". // The result must be confirmed later, after type checking, using embedKind. -func embedKindApprox(typ *Node) int { - if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) { +func embedKindApprox(typ ir.Node) int { + if typ.Sym() != nil && typ.Sym().Name == "FS" && (typ.Sym().Pkg.Path == "embed" || (typ.Sym().Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) { return embedFiles } // These are not guaranteed to match only string and []byte - // maybe the local package has redefined one of those words. // But it's the best we can do now during the noder. // The stricter check happens later, in initEmbed calling embedKind. - if typ.Sym != nil && typ.Sym.Name == "string" && typ.Sym.Pkg == localpkg { + if typ.Sym() != nil && typ.Sym().Name == "string" && typ.Sym().Pkg == ir.LocalPkg { return embedString } - if typ.Op == OTARRAY && typ.Left == nil && typ.Right.Sym != nil && typ.Right.Sym.Name == "byte" && typ.Right.Sym.Pkg == localpkg { + if typ.Op() == ir.OTARRAY && typ.Left() == nil && typ.Right().Sym() != nil && typ.Right().Sym().Name == "byte" && typ.Right().Sym().Pkg == ir.LocalPkg { return embedBytes } return embedUnknown @@ -170,10 +149,10 @@ func embedKindApprox(typ *Node) int { // embedKind determines the kind of embedding variable. func embedKind(typ *types.Type) int { - if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == localpkg && myimportpath == "embed")) { + if typ.Sym != nil && typ.Sym.Name == "FS" && (typ.Sym.Pkg.Path == "embed" || (typ.Sym.Pkg == ir.LocalPkg && base.Ctxt.Pkgpath == "embed")) { return embedFiles } - if typ == types.Types[TSTRING] { + if typ == types.Types[types.TSTRING] { return embedString } if typ.Sym == nil && typ.IsSlice() && typ.Elem() == types.Bytetype { @@ -213,19 +192,19 @@ 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 *Node) { - files := v.Name.Param.EmbedFiles() - switch kind := embedKind(v.Type); kind { +func initEmbed(v ir.Node) { + files := v.Name().Param.EmbedFiles() + switch kind := embedKind(v.Type()); kind { case embedUnknown: - yyerrorl(v.Pos, "go:embed cannot apply to var of type %v", v.Type) + base.ErrorfAt(v.Pos(), "go:embed cannot apply to var of type %v", v.Type()) case embedString, embedBytes: file := files[0] - fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], kind == embedString, nil) + fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], kind == embedString, nil) if err != nil { - yyerrorl(v.Pos, "embed %s: %v", file, err) + base.ErrorfAt(v.Pos(), "embed %s: %v", file, err) } - sym := v.Sym.Linksym() + sym := v.Sym().Linksym() off := 0 off = dsymptr(sym, off, fsym, 0) // data string off = duintptr(sym, off, uint64(size)) // len @@ -234,7 +213,7 @@ func initEmbed(v *Node) { } case embedFiles: - slicedata := Ctxt.Lookup(`"".` + v.Sym.Name + `.files`) + slicedata := base.Ctxt.Lookup(`"".` + v.Sym().Name + `.files`) off := 0 // []files pointed at by Files off = dsymptr(slicedata, off, slicedata, 3*Widthptr) // []file, pointing just past slice @@ -249,7 +228,7 @@ func initEmbed(v *Node) { const hashSize = 16 hash := make([]byte, hashSize) for _, file := range files { - off = dsymptr(slicedata, off, stringsym(v.Pos, file), 0) // file string + off = dsymptr(slicedata, off, stringsym(v.Pos(), file), 0) // file string off = duintptr(slicedata, off, uint64(len(file))) if strings.HasSuffix(file, "/") { // entry for directory - no data @@ -257,17 +236,17 @@ func initEmbed(v *Node) { off = duintptr(slicedata, off, 0) off += hashSize } else { - fsym, size, err := fileStringSym(v.Pos, embedCfg.Files[file], true, hash) + fsym, size, err := fileStringSym(v.Pos(), base.Flag.Cfg.Embed.Files[file], true, hash) if err != nil { - yyerrorl(v.Pos, "embed %s: %v", file, err) + base.ErrorfAt(v.Pos(), "embed %s: %v", file, err) } off = dsymptr(slicedata, off, fsym, 0) // data string off = duintptr(slicedata, off, uint64(size)) - off = int(slicedata.WriteBytes(Ctxt, int64(off), hash)) + off = int(slicedata.WriteBytes(base.Ctxt, int64(off), hash)) } } ggloblsym(slicedata, int32(off), obj.RODATA|obj.LOCAL) - sym := v.Sym.Linksym() + sym := v.Sym().Linksym() dsymptr(sym, 0, slicedata, 0) } } |