mirror of
https://github.com/golang/go
synced 2024-11-11 20:30:22 -07:00
[dev.regabi] cmd/compile: address some ir TODOs
Previously, ODOTTYPE/ODOTTYPE2 were forced to reuse some available Node fields for storing pointers to runtime type descriptors. This resulted in awkward field types for TypeAssertExpr and AddrExpr. This CL gives TypeAssertExpr proper fields for the runtime type descriptors, and also tightens the field types as possible/appropriate. Passes toolstash -cmp. Change-Id: I521ee7a1462affc5459de33a0de6c68a7d6416ba Reviewed-on: https://go-review.googlesource.com/c/go/+/280637 Trust: Matthew Dempsky <mdempsky@google.com> Trust: Dan Scales <danscales@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
4629f6a51d
commit
6acbae4fcc
@ -109,7 +109,7 @@ func NewAddStringExpr(pos src.XPos, list []Node) *AddStringExpr {
|
|||||||
type AddrExpr struct {
|
type AddrExpr struct {
|
||||||
miniExpr
|
miniExpr
|
||||||
X Node
|
X Node
|
||||||
Alloc Node // preallocated storage if any
|
Alloc *Name // preallocated storage if any
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
|
func NewAddrExpr(pos src.XPos, x Node) *AddrExpr {
|
||||||
@ -660,8 +660,13 @@ func (n *StarExpr) SetOTYPE(t *types.Type) {
|
|||||||
type TypeAssertExpr struct {
|
type TypeAssertExpr struct {
|
||||||
miniExpr
|
miniExpr
|
||||||
X Node
|
X Node
|
||||||
Ntype Node // TODO: Should be Ntype, but reused as address of type structure
|
Ntype Ntype
|
||||||
Itab Nodes // Itab[0] is itab
|
|
||||||
|
// Runtime type information provided by walkDotType.
|
||||||
|
// Caution: These aren't always populated; see walkDotType.
|
||||||
|
SrcType *AddrExpr // *runtime._type for X's type
|
||||||
|
DstType *AddrExpr // *runtime._type for Type
|
||||||
|
Itab *AddrExpr // *runtime.itab for Type implementing X's type
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {
|
func NewTypeAssertExpr(pos src.XPos, x Node, typ Ntype) *TypeAssertExpr {
|
||||||
|
@ -32,13 +32,11 @@ func (n *AddrExpr) doChildren(do func(Node) error) error {
|
|||||||
var err error
|
var err error
|
||||||
err = maybeDoList(n.init, err, do)
|
err = maybeDoList(n.init, err, do)
|
||||||
err = maybeDo(n.X, err, do)
|
err = maybeDo(n.X, err, do)
|
||||||
err = maybeDo(n.Alloc, err, do)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func (n *AddrExpr) editChildren(edit func(Node) Node) {
|
func (n *AddrExpr) editChildren(edit func(Node) Node) {
|
||||||
editList(n.init, edit)
|
editList(n.init, edit)
|
||||||
n.X = maybeEdit(n.X, edit)
|
n.X = maybeEdit(n.X, edit)
|
||||||
n.Alloc = maybeEdit(n.Alloc, edit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
func (n *ArrayType) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||||
@ -954,7 +952,6 @@ func (n *TypeAssertExpr) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
|||||||
func (n *TypeAssertExpr) copy() Node {
|
func (n *TypeAssertExpr) copy() Node {
|
||||||
c := *n
|
c := *n
|
||||||
c.init = c.init.Copy()
|
c.init = c.init.Copy()
|
||||||
c.Itab = c.Itab.Copy()
|
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
func (n *TypeAssertExpr) doChildren(do func(Node) error) error {
|
func (n *TypeAssertExpr) doChildren(do func(Node) error) error {
|
||||||
@ -962,14 +959,12 @@ func (n *TypeAssertExpr) doChildren(do func(Node) error) error {
|
|||||||
err = maybeDoList(n.init, err, do)
|
err = maybeDoList(n.init, err, do)
|
||||||
err = maybeDo(n.X, err, do)
|
err = maybeDo(n.X, err, do)
|
||||||
err = maybeDo(n.Ntype, err, do)
|
err = maybeDo(n.Ntype, err, do)
|
||||||
err = maybeDoList(n.Itab, err, do)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
func (n *TypeAssertExpr) editChildren(edit func(Node) Node) {
|
func (n *TypeAssertExpr) editChildren(edit func(Node) Node) {
|
||||||
editList(n.init, edit)
|
editList(n.init, edit)
|
||||||
n.X = maybeEdit(n.X, edit)
|
n.X = maybeEdit(n.X, edit)
|
||||||
n.Ntype = maybeEdit(n.Ntype, edit)
|
n.Ntype = toNtype(maybeEdit(n.Ntype, edit))
|
||||||
editList(n.Itab, edit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
func (n *TypeSwitchGuard) Format(s fmt.State, verb rune) { FmtNode(n, s, verb) }
|
||||||
|
@ -5979,7 +5979,7 @@ func (s *state) floatToUint(cvttab *f2uCvtTab, n ir.Node, x *ssa.Value, ft, tt *
|
|||||||
// If commaok is false, resok will be nil.
|
// If commaok is false, resok will be nil.
|
||||||
func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Value) {
|
func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Value) {
|
||||||
iface := s.expr(n.X) // input interface
|
iface := s.expr(n.X) // input interface
|
||||||
target := s.expr(n.Ntype) // target type
|
target := s.expr(n.DstType) // target type
|
||||||
byteptr := s.f.Config.Types.BytePtr
|
byteptr := s.f.Config.Types.BytePtr
|
||||||
|
|
||||||
if n.Type().IsInterface() {
|
if n.Type().IsInterface() {
|
||||||
@ -6086,7 +6086,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
|
|||||||
targetITab = target
|
targetITab = target
|
||||||
} else {
|
} else {
|
||||||
// Looking for pointer to itab for target type and source interface.
|
// Looking for pointer to itab for target type and source interface.
|
||||||
targetITab = s.expr(n.Itab[0])
|
targetITab = s.expr(n.Itab)
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmp ir.Node // temporary for use with large types
|
var tmp ir.Node // temporary for use with large types
|
||||||
@ -6113,7 +6113,7 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
|
|||||||
if !commaok {
|
if !commaok {
|
||||||
// on failure, panic by calling panicdottype
|
// on failure, panic by calling panicdottype
|
||||||
s.startBlock(bFail)
|
s.startBlock(bFail)
|
||||||
taddr := s.expr(n.Ntype.(*ir.AddrExpr).Alloc)
|
taddr := s.expr(n.SrcType)
|
||||||
if n.X.Type().IsEmptyInterface() {
|
if n.X.Type().IsEmptyInterface() {
|
||||||
s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr)
|
s.rtcall(ir.Syms.PanicdottypeE, false, nil, itab, target, taddr)
|
||||||
} else {
|
} else {
|
||||||
|
@ -649,7 +649,7 @@ func tcDotType(n *ir.TypeAssertExpr) ir.Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n.Ntype != nil {
|
if n.Ntype != nil {
|
||||||
n.Ntype = typecheck(n.Ntype, ctxType)
|
n.Ntype = typecheckNtype(n.Ntype)
|
||||||
n.SetType(n.Ntype.Type())
|
n.SetType(n.Ntype.Type())
|
||||||
n.Ntype = nil
|
n.Ntype = nil
|
||||||
if n.Type() == nil {
|
if n.Type() == nil {
|
||||||
|
@ -639,12 +639,13 @@ func walkDot(n *ir.SelectorExpr, init *ir.Nodes) ir.Node {
|
|||||||
func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node {
|
func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node {
|
||||||
n.X = walkExpr(n.X, init)
|
n.X = walkExpr(n.X, init)
|
||||||
// Set up interface type addresses for back end.
|
// Set up interface type addresses for back end.
|
||||||
n.Ntype = reflectdata.TypePtr(n.Type())
|
|
||||||
|
n.DstType = reflectdata.TypePtr(n.Type())
|
||||||
if n.Op() == ir.ODOTTYPE {
|
if n.Op() == ir.ODOTTYPE {
|
||||||
n.Ntype.(*ir.AddrExpr).Alloc = reflectdata.TypePtr(n.X.Type())
|
n.SrcType = reflectdata.TypePtr(n.X.Type())
|
||||||
}
|
}
|
||||||
if !n.Type().IsInterface() && !n.X.Type().IsEmptyInterface() {
|
if !n.Type().IsInterface() && !n.X.Type().IsEmptyInterface() {
|
||||||
n.Itab = []ir.Node{reflectdata.ITabAddr(n.Type(), n.X.Type())}
|
n.Itab = reflectdata.ITabAddr(n.Type(), n.X.Type())
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user