1
0
mirror of https://github.com/golang/go synced 2024-11-11 20:20:23 -07:00

[dev.regabi] cmd/compile: adjustments to Copy and DeepCopy

DeepCopy is not called DeepSepCopy, so it should use Copy, not SepCopy.

Also, the old gc.treecopy, which became ir.DeepCopy, only copied
the Left, Right, and List fields - not Init, Rlist, Body - and I didn't
notice when I moved it over. A general utility function should of
course copy the whole node, so do that.

Finally, the semantics of Copy should not depend on whether a
particular child node is held directly in a field or in a slice,
so make Copy duplicate the slice backing arrays as well.
(Logically, those backing arrays are part of the node storage.)

Passes buildall w/ toolstash -cmp.

Change-Id: I18fbe3f2b40078f566ed6370684d5585052b36a1
Reviewed-on: https://go-review.googlesource.com/c/go/+/275309
Trust: Russ Cox <rsc@golang.org>
Run-TryBot: Russ Cox <rsc@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Russ Cox 2020-12-02 22:42:24 -05:00
parent 99ecfcae31
commit 989a3f5041

View File

@ -61,9 +61,33 @@ func Copy(n Node) Node {
if n, ok := n.(OrigNode); ok && n.Orig() == n {
copy.(OrigNode).SetOrig(copy)
}
// Copy lists so that updates to n.List[0]
// don't affect copy.List[0] and vice versa,
// same as updates to Left and Right.
// TODO(rsc): Eventually the Node implementations will need to do this.
if l := copy.List(); l.Len() > 0 {
copy.SetList(copyList(l))
}
if l := copy.Rlist(); l.Len() > 0 {
copy.SetRlist(copyList(l))
}
if l := copy.Init(); l.Len() > 0 {
copy.SetInit(copyList(l))
}
if l := copy.Body(); l.Len() > 0 {
copy.SetBody(copyList(l))
}
return copy
}
func copyList(x Nodes) Nodes {
out := make([]Node, x.Len())
copy(out, x.Slice())
return AsNodes(out)
}
// A Node can implement DeepCopyNode to provide a custom implementation
// of DeepCopy. If the compiler only needs access to a Node's structure during
// DeepCopy, then a Node can implement DeepCopyNode instead of providing
@ -94,10 +118,15 @@ func DeepCopy(pos src.XPos, n Node) Node {
switch n.Op() {
default:
m := SepCopy(n)
m := Copy(n)
m.SetLeft(DeepCopy(pos, n.Left()))
m.SetRight(DeepCopy(pos, n.Right()))
m.PtrList().Set(deepCopyList(pos, n.List().Slice()))
// deepCopyList instead of DeepCopyList
// because Copy already copied all these slices.
deepCopyList(pos, m.PtrList().Slice())
deepCopyList(pos, m.PtrRlist().Slice())
deepCopyList(pos, m.PtrInit().Slice())
deepCopyList(pos, m.PtrBody().Slice())
if pos.IsKnown() {
m.SetPos(pos)
}
@ -118,10 +147,18 @@ func DeepCopy(pos src.XPos, n Node) Node {
}
}
func deepCopyList(pos src.XPos, list []Node) []Node {
// DeepCopyList returns a list of deep copies (using DeepCopy) of the nodes in list.
func DeepCopyList(pos src.XPos, list []Node) []Node {
var out []Node
for _, n := range list {
out = append(out, DeepCopy(pos, n))
}
return out
}
// deepCopyList edits list to point to deep copies of its elements.
func deepCopyList(pos src.XPos, list []Node) {
for i, n := range list {
list[i] = DeepCopy(pos, n)
}
}