diff options
author | Dan Scales <danscales@google.com> | 2020-12-01 14:48:03 -0800 |
---|---|---|
committer | Dan Scales <danscales@google.com> | 2021-01-20 22:53:32 +0000 |
commit | 1760d736f61265b3c78a6a48f2e1904341806643 (patch) | |
tree | fbf7575c435f30ae41e97589adeca569cbe0225e /src/cmd/compile/internal/typecheck/iexport.go | |
parent | 92cb157cf3aa51d28e441dbb2b671795f22140f8 (diff) | |
download | go-1760d736f61265b3c78a6a48f2e1904341806643.tar.gz go-1760d736f61265b3c78a6a48f2e1904341806643.zip |
[dev.regabi] cmd/compile: exporting, importing, and inlining functions with OCLOSURE
I have exporting, importing, and inlining of functions with closures
working in all cases (issue #28727). all.bash runs successfully without
errors.
Approach:
- Write out the Func type, Dcls, ClosureVars, and Body when exporting
an OCLOSURE.
- When importing an OCLOSURE, read in the type, dcls, closure vars,
and body, and then do roughly equivalent code to (*noder).funcLit
- During inlining of a closure within inlined function, create new
nodes for all params and local variables (including closure
variables), so they can have a new Curfn and some other field
values. Must substitute not only on the Nbody of the closure, but
also the Type, Cvars, and Dcl fields.
Fixes #28727
Change-Id: I4da1e2567c3fa31a5121afbe82dc4e5ee32b3170
Reviewed-on: https://go-review.googlesource.com/c/go/+/283112
Run-TryBot: Dan Scales <danscales@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Trust: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/iexport.go')
-rw-r--r-- | src/cmd/compile/internal/typecheck/iexport.go | 49 |
1 files changed, 40 insertions, 9 deletions
diff --git a/src/cmd/compile/internal/typecheck/iexport.go b/src/cmd/compile/internal/typecheck/iexport.go index 1ba8771139..be4a689836 100644 --- a/src/cmd/compile/internal/typecheck/iexport.go +++ b/src/cmd/compile/internal/typecheck/iexport.go @@ -423,9 +423,13 @@ type exportWriter struct { prevLine int64 prevColumn int64 - // dclIndex maps function-scoped declarations to their index - // within their respective Func's Dcl list. - dclIndex map[*ir.Name]int + // dclIndex maps function-scoped declarations to an int used to refer to + // them later in the function. For local variables/params, the int is + // non-negative and in order of the appearance in the Func's Dcl list. For + // closure variables, the index is negative starting at -2. + dclIndex map[*ir.Name]int + maxDclIndex int + maxClosureVarIndex int } func (p *iexporter) doDecl(n *ir.Name) { @@ -1038,14 +1042,19 @@ func (w *exportWriter) typeExt(t *types.Type) { // Inline bodies. -func (w *exportWriter) funcBody(fn *ir.Func) { - w.int64(int64(len(fn.Inl.Dcl))) - for i, n := range fn.Inl.Dcl { +func (w *exportWriter) writeNames(dcl []*ir.Name) { + w.int64(int64(len(dcl))) + for i, n := range dcl { w.pos(n.Pos()) w.localIdent(n.Sym()) w.typ(n.Type()) - w.dclIndex[n] = i + w.dclIndex[n] = w.maxDclIndex + i } + w.maxDclIndex += len(dcl) +} + +func (w *exportWriter) funcBody(fn *ir.Func) { + w.writeNames(fn.Inl.Dcl) w.stmtList(fn.Inl.Body) } @@ -1315,8 +1324,30 @@ func (w *exportWriter) expr(n ir.Node) { // case OTARRAY, OTMAP, OTCHAN, OTSTRUCT, OTINTER, OTFUNC: // should have been resolved by typechecking - handled by default case - // case OCLOSURE: - // unimplemented - handled by default case + case ir.OCLOSURE: + n := n.(*ir.ClosureExpr) + w.op(ir.OCLOSURE) + w.pos(n.Pos()) + w.signature(n.Type()) + + // Write out id for the Outer of each conditional variable. The + // conditional variable itself for this closure will be re-created + // during import. + w.int64(int64(len(n.Func.ClosureVars))) + for i, cv := range n.Func.ClosureVars { + w.pos(cv.Pos()) + w.localName(cv.Outer) + // Closure variable (which will be re-created during + // import) is given via a negative id, starting at -2, + // which is used to refer to it later in the function + // during export. -1 represents blanks. + w.dclIndex[cv] = -(i + 2) - w.maxClosureVarIndex + } + w.maxClosureVarIndex += len(n.Func.ClosureVars) + + // like w.funcBody(n.Func), but not for .Inl + w.writeNames(n.Func.Dcl) + w.stmtList(n.Func.Body) // case OCOMPLIT: // should have been resolved by typechecking - handled by default case |