diff options
| author | Russ Cox <rsc@golang.org> | 2020-07-19 00:32:02 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2020-10-23 00:29:10 +0000 |
| commit | 8bde9b320e25b2d6edf96fa5e694046fea0c04c8 (patch) | |
| tree | e279ac87b40f2bb560ecab337609d726534fb820 /src/cmd/internal/obj/objfile.go | |
| parent | 400581b8b008ece8d0df34f54f281d365a175dba (diff) | |
| download | go-8bde9b320e25b2d6edf96fa5e694046fea0c04c8.tar.xz | |
cmd/compile: add //go:embed support
This commit contains the compiler support for //go:embed lines.
The go command passes to the compiler an "embed config"
that maps literal patterns like *.txt to the set of files to embed.
The compiler then lays out the content of those files as static data
in the form of an embed.Files or string or []byte in the final object file.
The test for this code is the end-to-end test hooking up the
embed, cmd/compile, and cmd/go changes, in the next CL.
For #41191.
Change-Id: I916e57f8cc65871dc0044c13d3f90c252a3fe1bf
Reviewed-on: https://go-review.googlesource.com/c/go/+/243944
Trust: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'src/cmd/internal/obj/objfile.go')
| -rw-r--r-- | src/cmd/internal/obj/objfile.go | 49 |
1 files changed, 45 insertions, 4 deletions
diff --git a/src/cmd/internal/obj/objfile.go b/src/cmd/internal/obj/objfile.go index a24a7b878f..bb58b4f0c2 100644 --- a/src/cmd/internal/obj/objfile.go +++ b/src/cmd/internal/obj/objfile.go @@ -16,6 +16,8 @@ import ( "encoding/binary" "fmt" "io" + "log" + "os" "path/filepath" "sort" "strings" @@ -147,14 +149,20 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { // Data indexes h.Offsets[goobj.BlkDataIdx] = w.Offset() - dataOff := uint32(0) + dataOff := int64(0) for _, list := range lists { for _, s := range list { - w.Uint32(dataOff) - dataOff += uint32(len(s.P)) + w.Uint32(uint32(dataOff)) + dataOff += int64(len(s.P)) + if file := s.File(); file != nil { + dataOff += int64(file.Size) + } } } - w.Uint32(dataOff) + if int64(uint32(dataOff)) != dataOff { + log.Fatalf("data too large") + } + w.Uint32(uint32(dataOff)) // Relocs h.Offsets[goobj.BlkReloc] = w.Offset() @@ -179,6 +187,9 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { for _, list := range lists { for _, s := range list { w.Bytes(s.P) + if file := s.File(); file != nil { + w.writeFile(ctxt, file) + } } } @@ -218,6 +229,7 @@ func WriteObjFile(ctxt *Link, b *bio.Writer) { type writer struct { *goobj.Writer + filebuf []byte ctxt *Link pkgpath string // the package import path (escaped), "" if unknown pkglist []string // list of packages referenced, indexed by ctxt.pkgIdx @@ -232,6 +244,35 @@ func (w *writer) init() { } } +func (w *writer) writeFile(ctxt *Link, file *FileInfo) { + f, err := os.Open(file.Name) + if err != nil { + ctxt.Diag("%v", err) + return + } + defer f.Close() + if w.filebuf == nil { + w.filebuf = make([]byte, 1024) + } + buf := w.filebuf + written := int64(0) + for { + n, err := f.Read(buf) + w.Bytes(buf[:n]) + written += int64(n) + if err == io.EOF { + break + } + if err != nil { + ctxt.Diag("%v", err) + return + } + } + if written != file.Size { + ctxt.Diag("copy %s: unexpected length %d != %d", file.Name, written, file.Size) + } +} + func (w *writer) StringTable() { w.AddString("") for _, p := range w.ctxt.Imports { |
