aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/gc/embed.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/compile/internal/gc/embed.go')
-rw-r--r--src/cmd/compile/internal/gc/embed.go107
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)
}
}