aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck/iexport.go
diff options
context:
space:
mode:
authorMatthew Dempsky <mdempsky@google.com>2021-01-11 15:07:09 -0800
committerMatthew Dempsky <mdempsky@google.com>2021-01-12 03:15:18 +0000
commit12ee55ba7bf22157267e735e8e4bbf651c5b4e7d (patch)
treea024598854c7bc9f41d4e7497c2c07cb52a9c4cf /src/cmd/compile/internal/typecheck/iexport.go
parentb4d2a0445b0ca54a159e0895e1a8b31d47411894 (diff)
downloadgo-12ee55ba7bf22157267e735e8e4bbf651c5b4e7d.tar.gz
go-12ee55ba7bf22157267e735e8e4bbf651c5b4e7d.zip
[dev.regabi] cmd/compile: stop using Vargen for import/export
Historically, inline function bodies were exported as plain Go source code, and symbol mangling was a convenient hack because it allowed variables to be re-imported with largely the same names as they were originally exported as. However, nowadays we use a binary format that's more easily extended, so we can simply serialize all of a function's declared objects up front, and then refer to them by index later on. This also allows us to easily report unmangled names all the time (e.g., error message from issue7921.go). Fixes #43633. Change-Id: I46c88f5a47cb921f70ab140976ba9ddce38df216 Reviewed-on: https://go-review.googlesource.com/c/go/+/283193 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com> Trust: Dan Scales <danscales@google.com> Trust: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/iexport.go')
-rw-r--r--src/cmd/compile/internal/typecheck/iexport.go58
1 files changed, 33 insertions, 25 deletions
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go
index a7927c39a3..4d48b80346 100644
--- a/src/cmd/compile/internal/typecheck/iexport.go
+++ b/src/cmd/compile/internal/typecheck/iexport.go
@@ -422,6 +422,10 @@ type exportWriter struct {
prevFile string
prevLine int64
prevColumn int64
+
+ // dclIndex maps function-scoped declarations to their index
+ // within their respective Func's Dcl list.
+ dclIndex map[*ir.Name]int
}
func (p *iexporter) doDecl(n *ir.Name) {
@@ -529,7 +533,8 @@ func (p *iexporter) doInline(f *ir.Name) {
w := p.newWriter()
w.setPkg(fnpkg(f), false)
- w.stmtList(ir.Nodes(f.Func.Inl.Body))
+ w.dclIndex = make(map[*ir.Name]int, len(f.Func.Inl.Dcl))
+ w.funcBody(f.Func)
w.finish("inl", p.inlineIndex, f.Sym())
}
@@ -756,7 +761,7 @@ func (w *exportWriter) paramList(fs []*types.Field) {
func (w *exportWriter) param(f *types.Field) {
w.pos(f.Pos)
- w.localIdent(types.OrigSym(f.Sym), 0)
+ w.localIdent(types.OrigSym(f.Sym))
w.typ(f.Type)
}
@@ -1030,7 +1035,19 @@ func (w *exportWriter) typeExt(t *types.Type) {
// Inline bodies.
-func (w *exportWriter) stmtList(list ir.Nodes) {
+func (w *exportWriter) funcBody(fn *ir.Func) {
+ w.int64(int64(len(fn.Inl.Dcl)))
+ for i, n := range fn.Inl.Dcl {
+ w.pos(n.Pos())
+ w.localIdent(n.Sym())
+ w.typ(n.Type())
+ w.dclIndex[n] = i
+ }
+
+ w.stmtList(fn.Inl.Body)
+}
+
+func (w *exportWriter) stmtList(list []ir.Node) {
for _, n := range list {
w.node(n)
}
@@ -1070,10 +1087,11 @@ func (w *exportWriter) stmt(n ir.Node) {
case ir.ODCL:
n := n.(*ir.Decl)
+ if ir.IsBlank(n.X) {
+ return // blank declarations not useful to importers
+ }
w.op(ir.ODCL)
- w.pos(n.X.Pos())
w.localName(n.X)
- w.typ(n.X.Type())
case ir.OAS:
// Don't export "v = <N>" initializing statements, hope they're always
@@ -1288,7 +1306,7 @@ func (w *exportWriter) expr(n ir.Node) {
}
s = n.Tag.Sym()
}
- w.localIdent(s, 0) // declared pseudo-variable, if any
+ w.localIdent(s) // declared pseudo-variable, if any
w.expr(n.X)
// case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC:
@@ -1518,22 +1536,19 @@ func (w *exportWriter) fieldList(list ir.Nodes) {
}
func (w *exportWriter) localName(n *ir.Name) {
- // Escape analysis happens after inline bodies are saved, but
- // we're using the same ONAME nodes, so we might still see
- // PAUTOHEAP here.
- //
- // Check for Stackcopy to identify PAUTOHEAP that came from
- // PPARAM/PPARAMOUT, because we only want to include vargen in
- // non-param names.
- var v int32
- if n.Class == ir.PAUTO || (n.Class == ir.PAUTOHEAP && n.Stackcopy == nil) {
- v = n.Vargen
+ if ir.IsBlank(n) {
+ w.int64(-1)
+ return
}
- w.localIdent(n.Sym(), v)
+ i, ok := w.dclIndex[n]
+ if !ok {
+ base.FatalfAt(n.Pos(), "missing from dclIndex: %+v", n)
+ }
+ w.int64(int64(i))
}
-func (w *exportWriter) localIdent(s *types.Sym, v int32) {
+func (w *exportWriter) localIdent(s *types.Sym) {
if w.currPkg == nil {
base.Fatalf("missing currPkg")
}
@@ -1555,13 +1570,6 @@ func (w *exportWriter) localIdent(s *types.Sym, v int32) {
base.Fatalf("unexpected dot in identifier: %v", name)
}
- if v > 0 {
- if strings.Contains(name, "·") {
- base.Fatalf("exporter: unexpected · in symbol name")
- }
- name = fmt.Sprintf("%s·%d", name, v)
- }
-
if s.Pkg != w.currPkg {
base.Fatalf("weird package in name: %v => %v from %q, not %q", s, name, s.Pkg.Path, w.currPkg.Path)
}