mirror of
https://github.com/golang/go
synced 2024-09-05 07:54:46 +00:00
[dev.typeparams] cmd/compile: introduce OCONVIDATA op
This operation computes just the data field needed to put its argument into an interface. Used by generics because we produce the type field of an interface using dictionaries (instead of statically). With this operation defined, we can now assert that shape types are never marked as used in interfaces (the only previous use was IDATA(CONVIFACE(t))). Change-Id: Idb1eb5f3b238285cb99413d382599c0621b7681a Reviewed-on: https://go-review.googlesource.com/c/go/+/337109 Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
This commit is contained in:
parent
9f928f9318
commit
77e0bf294c
|
@ -109,7 +109,7 @@ func (e *escape) exprSkipInit(k hole, n ir.Node) {
|
||||||
} else {
|
} else {
|
||||||
e.expr(k, n.X)
|
e.expr(k, n.X)
|
||||||
}
|
}
|
||||||
case ir.OCONVIFACE:
|
case ir.OCONVIFACE, ir.OCONVIDATA:
|
||||||
n := n.(*ir.ConvExpr)
|
n := n.(*ir.ConvExpr)
|
||||||
if !n.X.Type().IsInterface() && !types.IsDirectIface(n.X.Type()) {
|
if !n.X.Type().IsInterface() && !types.IsDirectIface(n.X.Type()) {
|
||||||
k = e.spill(k, n)
|
k = e.spill(k, n)
|
||||||
|
|
|
@ -270,7 +270,7 @@ func (n *ConvExpr) SetOp(op Op) {
|
||||||
switch op {
|
switch op {
|
||||||
default:
|
default:
|
||||||
panic(n.no("SetOp " + op.String()))
|
panic(n.no("SetOp " + op.String()))
|
||||||
case OCONV, OCONVIFACE, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
|
case OCONV, OCONVIFACE, OCONVIDATA, OCONVNOP, OBYTES2STR, OBYTES2STRTMP, ORUNES2STR, OSTR2BYTES, OSTR2BYTESTMP, OSTR2RUNES, ORUNESTR, OSLICE2ARRPTR:
|
||||||
n.op = op
|
n.op = op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -185,6 +185,7 @@ var OpPrec = []int{
|
||||||
OCLOSE: 8,
|
OCLOSE: 8,
|
||||||
OCOMPLIT: 8,
|
OCOMPLIT: 8,
|
||||||
OCONVIFACE: 8,
|
OCONVIFACE: 8,
|
||||||
|
OCONVIDATA: 8,
|
||||||
OCONVNOP: 8,
|
OCONVNOP: 8,
|
||||||
OCONV: 8,
|
OCONV: 8,
|
||||||
OCOPY: 8,
|
OCOPY: 8,
|
||||||
|
@ -546,7 +547,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
|
||||||
n = nn.X
|
n = nn.X
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
case OCONV, OCONVNOP, OCONVIFACE:
|
case OCONV, OCONVNOP, OCONVIFACE, OCONVIDATA:
|
||||||
nn := nn.(*ConvExpr)
|
nn := nn.(*ConvExpr)
|
||||||
if nn.Implicit() {
|
if nn.Implicit() {
|
||||||
n = nn.X
|
n = nn.X
|
||||||
|
@ -813,6 +814,7 @@ func exprFmt(n Node, s fmt.State, prec int) {
|
||||||
|
|
||||||
case OCONV,
|
case OCONV,
|
||||||
OCONVIFACE,
|
OCONVIFACE,
|
||||||
|
OCONVIDATA,
|
||||||
OCONVNOP,
|
OCONVNOP,
|
||||||
OBYTES2STR,
|
OBYTES2STR,
|
||||||
ORUNES2STR,
|
ORUNES2STR,
|
||||||
|
|
|
@ -170,6 +170,7 @@ const (
|
||||||
OPTRLIT // &X (X is composite literal)
|
OPTRLIT // &X (X is composite literal)
|
||||||
OCONV // Type(X) (type conversion)
|
OCONV // Type(X) (type conversion)
|
||||||
OCONVIFACE // Type(X) (type conversion, to interface)
|
OCONVIFACE // Type(X) (type conversion, to interface)
|
||||||
|
OCONVIDATA // Builds a data word to store X in an interface. Equivalent to IDATA(CONVIFACE(X)). Is an ir.ConvExpr.
|
||||||
OCONVNOP // Type(X) (type conversion, no effect)
|
OCONVNOP // Type(X) (type conversion, no effect)
|
||||||
OCOPY // copy(X, Y)
|
OCOPY // copy(X, Y)
|
||||||
ODCL // var X (declares X of type X.Type)
|
ODCL // var X (declares X of type X.Type)
|
||||||
|
|
|
@ -52,125 +52,126 @@ func _() {
|
||||||
_ = x[OPTRLIT-41]
|
_ = x[OPTRLIT-41]
|
||||||
_ = x[OCONV-42]
|
_ = x[OCONV-42]
|
||||||
_ = x[OCONVIFACE-43]
|
_ = x[OCONVIFACE-43]
|
||||||
_ = x[OCONVNOP-44]
|
_ = x[OCONVIDATA-44]
|
||||||
_ = x[OCOPY-45]
|
_ = x[OCONVNOP-45]
|
||||||
_ = x[ODCL-46]
|
_ = x[OCOPY-46]
|
||||||
_ = x[ODCLFUNC-47]
|
_ = x[ODCL-47]
|
||||||
_ = x[ODCLCONST-48]
|
_ = x[ODCLFUNC-48]
|
||||||
_ = x[ODCLTYPE-49]
|
_ = x[ODCLCONST-49]
|
||||||
_ = x[ODELETE-50]
|
_ = x[ODCLTYPE-50]
|
||||||
_ = x[ODOT-51]
|
_ = x[ODELETE-51]
|
||||||
_ = x[ODOTPTR-52]
|
_ = x[ODOT-52]
|
||||||
_ = x[ODOTMETH-53]
|
_ = x[ODOTPTR-53]
|
||||||
_ = x[ODOTINTER-54]
|
_ = x[ODOTMETH-54]
|
||||||
_ = x[OXDOT-55]
|
_ = x[ODOTINTER-55]
|
||||||
_ = x[ODOTTYPE-56]
|
_ = x[OXDOT-56]
|
||||||
_ = x[ODOTTYPE2-57]
|
_ = x[ODOTTYPE-57]
|
||||||
_ = x[OEQ-58]
|
_ = x[ODOTTYPE2-58]
|
||||||
_ = x[ONE-59]
|
_ = x[OEQ-59]
|
||||||
_ = x[OLT-60]
|
_ = x[ONE-60]
|
||||||
_ = x[OLE-61]
|
_ = x[OLT-61]
|
||||||
_ = x[OGE-62]
|
_ = x[OLE-62]
|
||||||
_ = x[OGT-63]
|
_ = x[OGE-63]
|
||||||
_ = x[ODEREF-64]
|
_ = x[OGT-64]
|
||||||
_ = x[OINDEX-65]
|
_ = x[ODEREF-65]
|
||||||
_ = x[OINDEXMAP-66]
|
_ = x[OINDEX-66]
|
||||||
_ = x[OKEY-67]
|
_ = x[OINDEXMAP-67]
|
||||||
_ = x[OSTRUCTKEY-68]
|
_ = x[OKEY-68]
|
||||||
_ = x[OLEN-69]
|
_ = x[OSTRUCTKEY-69]
|
||||||
_ = x[OMAKE-70]
|
_ = x[OLEN-70]
|
||||||
_ = x[OMAKECHAN-71]
|
_ = x[OMAKE-71]
|
||||||
_ = x[OMAKEMAP-72]
|
_ = x[OMAKECHAN-72]
|
||||||
_ = x[OMAKESLICE-73]
|
_ = x[OMAKEMAP-73]
|
||||||
_ = x[OMAKESLICECOPY-74]
|
_ = x[OMAKESLICE-74]
|
||||||
_ = x[OMUL-75]
|
_ = x[OMAKESLICECOPY-75]
|
||||||
_ = x[ODIV-76]
|
_ = x[OMUL-76]
|
||||||
_ = x[OMOD-77]
|
_ = x[ODIV-77]
|
||||||
_ = x[OLSH-78]
|
_ = x[OMOD-78]
|
||||||
_ = x[ORSH-79]
|
_ = x[OLSH-79]
|
||||||
_ = x[OAND-80]
|
_ = x[ORSH-80]
|
||||||
_ = x[OANDNOT-81]
|
_ = x[OAND-81]
|
||||||
_ = x[ONEW-82]
|
_ = x[OANDNOT-82]
|
||||||
_ = x[ONOT-83]
|
_ = x[ONEW-83]
|
||||||
_ = x[OBITNOT-84]
|
_ = x[ONOT-84]
|
||||||
_ = x[OPLUS-85]
|
_ = x[OBITNOT-85]
|
||||||
_ = x[ONEG-86]
|
_ = x[OPLUS-86]
|
||||||
_ = x[OOROR-87]
|
_ = x[ONEG-87]
|
||||||
_ = x[OPANIC-88]
|
_ = x[OOROR-88]
|
||||||
_ = x[OPRINT-89]
|
_ = x[OPANIC-89]
|
||||||
_ = x[OPRINTN-90]
|
_ = x[OPRINT-90]
|
||||||
_ = x[OPAREN-91]
|
_ = x[OPRINTN-91]
|
||||||
_ = x[OSEND-92]
|
_ = x[OPAREN-92]
|
||||||
_ = x[OSLICE-93]
|
_ = x[OSEND-93]
|
||||||
_ = x[OSLICEARR-94]
|
_ = x[OSLICE-94]
|
||||||
_ = x[OSLICESTR-95]
|
_ = x[OSLICEARR-95]
|
||||||
_ = x[OSLICE3-96]
|
_ = x[OSLICESTR-96]
|
||||||
_ = x[OSLICE3ARR-97]
|
_ = x[OSLICE3-97]
|
||||||
_ = x[OSLICEHEADER-98]
|
_ = x[OSLICE3ARR-98]
|
||||||
_ = x[ORECOVER-99]
|
_ = x[OSLICEHEADER-99]
|
||||||
_ = x[ORECOVERFP-100]
|
_ = x[ORECOVER-100]
|
||||||
_ = x[ORECV-101]
|
_ = x[ORECOVERFP-101]
|
||||||
_ = x[ORUNESTR-102]
|
_ = x[ORECV-102]
|
||||||
_ = x[OSELRECV2-103]
|
_ = x[ORUNESTR-103]
|
||||||
_ = x[OIOTA-104]
|
_ = x[OSELRECV2-104]
|
||||||
_ = x[OREAL-105]
|
_ = x[OIOTA-105]
|
||||||
_ = x[OIMAG-106]
|
_ = x[OREAL-106]
|
||||||
_ = x[OCOMPLEX-107]
|
_ = x[OIMAG-107]
|
||||||
_ = x[OALIGNOF-108]
|
_ = x[OCOMPLEX-108]
|
||||||
_ = x[OOFFSETOF-109]
|
_ = x[OALIGNOF-109]
|
||||||
_ = x[OSIZEOF-110]
|
_ = x[OOFFSETOF-110]
|
||||||
_ = x[OUNSAFEADD-111]
|
_ = x[OSIZEOF-111]
|
||||||
_ = x[OUNSAFESLICE-112]
|
_ = x[OUNSAFEADD-112]
|
||||||
_ = x[OMETHEXPR-113]
|
_ = x[OUNSAFESLICE-113]
|
||||||
_ = x[OMETHVALUE-114]
|
_ = x[OMETHEXPR-114]
|
||||||
_ = x[OBLOCK-115]
|
_ = x[OMETHVALUE-115]
|
||||||
_ = x[OBREAK-116]
|
_ = x[OBLOCK-116]
|
||||||
_ = x[OCASE-117]
|
_ = x[OBREAK-117]
|
||||||
_ = x[OCONTINUE-118]
|
_ = x[OCASE-118]
|
||||||
_ = x[ODEFER-119]
|
_ = x[OCONTINUE-119]
|
||||||
_ = x[OFALL-120]
|
_ = x[ODEFER-120]
|
||||||
_ = x[OFOR-121]
|
_ = x[OFALL-121]
|
||||||
_ = x[OFORUNTIL-122]
|
_ = x[OFOR-122]
|
||||||
_ = x[OGOTO-123]
|
_ = x[OFORUNTIL-123]
|
||||||
_ = x[OIF-124]
|
_ = x[OGOTO-124]
|
||||||
_ = x[OLABEL-125]
|
_ = x[OIF-125]
|
||||||
_ = x[OGO-126]
|
_ = x[OLABEL-126]
|
||||||
_ = x[ORANGE-127]
|
_ = x[OGO-127]
|
||||||
_ = x[ORETURN-128]
|
_ = x[ORANGE-128]
|
||||||
_ = x[OSELECT-129]
|
_ = x[ORETURN-129]
|
||||||
_ = x[OSWITCH-130]
|
_ = x[OSELECT-130]
|
||||||
_ = x[OTYPESW-131]
|
_ = x[OSWITCH-131]
|
||||||
_ = x[OFUNCINST-132]
|
_ = x[OTYPESW-132]
|
||||||
_ = x[OTCHAN-133]
|
_ = x[OFUNCINST-133]
|
||||||
_ = x[OTMAP-134]
|
_ = x[OTCHAN-134]
|
||||||
_ = x[OTSTRUCT-135]
|
_ = x[OTMAP-135]
|
||||||
_ = x[OTINTER-136]
|
_ = x[OTSTRUCT-136]
|
||||||
_ = x[OTFUNC-137]
|
_ = x[OTINTER-137]
|
||||||
_ = x[OTARRAY-138]
|
_ = x[OTFUNC-138]
|
||||||
_ = x[OTSLICE-139]
|
_ = x[OTARRAY-139]
|
||||||
_ = x[OINLCALL-140]
|
_ = x[OTSLICE-140]
|
||||||
_ = x[OEFACE-141]
|
_ = x[OINLCALL-141]
|
||||||
_ = x[OITAB-142]
|
_ = x[OEFACE-142]
|
||||||
_ = x[OIDATA-143]
|
_ = x[OITAB-143]
|
||||||
_ = x[OSPTR-144]
|
_ = x[OIDATA-144]
|
||||||
_ = x[OCFUNC-145]
|
_ = x[OSPTR-145]
|
||||||
_ = x[OCHECKNIL-146]
|
_ = x[OCFUNC-146]
|
||||||
_ = x[OVARDEF-147]
|
_ = x[OCHECKNIL-147]
|
||||||
_ = x[OVARKILL-148]
|
_ = x[OVARDEF-148]
|
||||||
_ = x[OVARLIVE-149]
|
_ = x[OVARKILL-149]
|
||||||
_ = x[ORESULT-150]
|
_ = x[OVARLIVE-150]
|
||||||
_ = x[OINLMARK-151]
|
_ = x[ORESULT-151]
|
||||||
_ = x[OLINKSYMOFFSET-152]
|
_ = x[OINLMARK-152]
|
||||||
_ = x[OTAILCALL-153]
|
_ = x[OLINKSYMOFFSET-153]
|
||||||
_ = x[OGETG-154]
|
_ = x[OTAILCALL-154]
|
||||||
_ = x[OGETCALLERPC-155]
|
_ = x[OGETG-155]
|
||||||
_ = x[OGETCALLERSP-156]
|
_ = x[OGETCALLERPC-156]
|
||||||
_ = x[OEND-157]
|
_ = x[OGETCALLERSP-157]
|
||||||
|
_ = x[OEND-158]
|
||||||
}
|
}
|
||||||
|
|
||||||
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGGETCALLERPCGETCALLERSPEND"
|
const _Op_name = "XXXNAMENONAMETYPEPACKLITERALNILADDSUBORXORADDSTRADDRANDANDAPPENDBYTES2STRBYTES2STRTMPRUNES2STRSTR2BYTESSTR2BYTESTMPSTR2RUNESSLICE2ARRPTRASAS2AS2DOTTYPEAS2FUNCAS2MAPRAS2RECVASOPCALLCALLFUNCCALLMETHCALLINTERCAPCLOSECLOSURECOMPLITMAPLITSTRUCTLITARRAYLITSLICELITPTRLITCONVCONVIFACECONVIDATACONVNOPCOPYDCLDCLFUNCDCLCONSTDCLTYPEDELETEDOTDOTPTRDOTMETHDOTINTERXDOTDOTTYPEDOTTYPE2EQNELTLEGEGTDEREFINDEXINDEXMAPKEYSTRUCTKEYLENMAKEMAKECHANMAKEMAPMAKESLICEMAKESLICECOPYMULDIVMODLSHRSHANDANDNOTNEWNOTBITNOTPLUSNEGORORPANICPRINTPRINTNPARENSENDSLICESLICEARRSLICESTRSLICE3SLICE3ARRSLICEHEADERRECOVERRECOVERFPRECVRUNESTRSELRECV2IOTAREALIMAGCOMPLEXALIGNOFOFFSETOFSIZEOFUNSAFEADDUNSAFESLICEMETHEXPRMETHVALUEBLOCKBREAKCASECONTINUEDEFERFALLFORFORUNTILGOTOIFLABELGORANGERETURNSELECTSWITCHTYPESWFUNCINSTTCHANTMAPTSTRUCTTINTERTFUNCTARRAYTSLICEINLCALLEFACEITABIDATASPTRCFUNCCHECKNILVARDEFVARKILLVARLIVERESULTINLMARKLINKSYMOFFSETTAILCALLGETGGETCALLERPCGETCALLERSPEND"
|
||||||
|
|
||||||
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 136, 138, 141, 151, 158, 165, 172, 176, 180, 188, 196, 205, 208, 213, 220, 227, 233, 242, 250, 258, 264, 268, 277, 284, 288, 291, 298, 306, 313, 319, 322, 328, 335, 343, 347, 354, 362, 364, 366, 368, 370, 372, 374, 379, 384, 392, 395, 404, 407, 411, 419, 426, 435, 448, 451, 454, 457, 460, 463, 466, 472, 475, 478, 484, 488, 491, 495, 500, 505, 511, 516, 520, 525, 533, 541, 547, 556, 567, 574, 583, 587, 594, 602, 606, 610, 614, 621, 628, 636, 642, 651, 662, 670, 679, 684, 689, 693, 701, 706, 710, 713, 721, 725, 727, 732, 734, 739, 745, 751, 757, 763, 771, 776, 780, 787, 793, 798, 804, 810, 817, 822, 826, 831, 835, 840, 848, 854, 861, 868, 874, 881, 894, 902, 906, 917, 928, 931}
|
var _Op_index = [...]uint16{0, 3, 7, 13, 17, 21, 28, 31, 34, 37, 39, 42, 48, 52, 58, 64, 73, 85, 94, 103, 115, 124, 136, 138, 141, 151, 158, 165, 172, 176, 180, 188, 196, 205, 208, 213, 220, 227, 233, 242, 250, 258, 264, 268, 277, 286, 293, 297, 300, 307, 315, 322, 328, 331, 337, 344, 352, 356, 363, 371, 373, 375, 377, 379, 381, 383, 388, 393, 401, 404, 413, 416, 420, 428, 435, 444, 457, 460, 463, 466, 469, 472, 475, 481, 484, 487, 493, 497, 500, 504, 509, 514, 520, 525, 529, 534, 542, 550, 556, 565, 576, 583, 592, 596, 603, 611, 615, 619, 623, 630, 637, 645, 651, 660, 671, 679, 688, 693, 698, 702, 710, 715, 719, 722, 730, 734, 736, 741, 743, 748, 754, 760, 766, 772, 780, 785, 789, 796, 802, 807, 813, 819, 826, 831, 835, 840, 844, 849, 857, 863, 870, 877, 883, 890, 903, 911, 915, 926, 937, 940}
|
||||||
|
|
||||||
func (i Op) String() string {
|
func (i Op) String() string {
|
||||||
if i >= Op(len(_Op_index)-1) {
|
if i >= Op(len(_Op_index)-1) {
|
||||||
|
|
|
@ -1461,24 +1461,18 @@ func (subst *subster) convertUsingDictionary(pos src.XPos, v ir.Node, gn ir.Node
|
||||||
rt = subst.getDictionaryType(pos, ix)
|
rt = subst.getDictionaryType(pos, ix)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert value to an interface type, so the data field is what we want.
|
// Figure out what the data field of the interface will be.
|
||||||
if !v.Type().IsInterface() {
|
var data ir.Node
|
||||||
v = ir.NewConvExpr(v.Pos(), ir.OCONVIFACE, nil, v)
|
if v.Type().IsInterface() {
|
||||||
typed(types.NewInterface(types.LocalPkg, nil), v)
|
data = ir.NewUnaryExpr(pos, ir.OIDATA, v)
|
||||||
|
} else {
|
||||||
|
data = ir.NewConvExpr(pos, ir.OCONVIDATA, nil, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, v is an interface type with a data word we want.
|
|
||||||
// But the type word represents a gcshape type, which we don't want.
|
|
||||||
// Replace with the instantiated type loaded from the dictionary.
|
|
||||||
data := ir.NewUnaryExpr(pos, ir.OIDATA, v)
|
|
||||||
typed(types.Types[types.TUNSAFEPTR], data)
|
typed(types.Types[types.TUNSAFEPTR], data)
|
||||||
|
|
||||||
|
// Build an interface from the type and data parts.
|
||||||
var i ir.Node = ir.NewBinaryExpr(pos, ir.OEFACE, rt, data)
|
var i ir.Node = ir.NewBinaryExpr(pos, ir.OEFACE, rt, data)
|
||||||
typed(dst, i)
|
typed(dst, i)
|
||||||
// TODO: we're throwing away the type word of the original version
|
|
||||||
// of m here (it would be OITAB(m)), which probably took some
|
|
||||||
// work to generate. Can we avoid generating it at all?
|
|
||||||
// (The linker will throw them away if not needed, so it would just
|
|
||||||
// save toolchain work, not binary size.)
|
|
||||||
return i
|
return i
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1983,10 +1983,8 @@ var ZeroSize int64
|
||||||
// This information is used in the linker in dead method elimination.
|
// This information is used in the linker in dead method elimination.
|
||||||
func MarkTypeUsedInInterface(t *types.Type, from *obj.LSym) {
|
func MarkTypeUsedInInterface(t *types.Type, from *obj.LSym) {
|
||||||
if t.HasShape() {
|
if t.HasShape() {
|
||||||
// TODO: shape types shouldn't be put in interfaces, so we shouldn't ever get here.
|
// Shape types shouldn't be put in interfaces, so we shouldn't ever get here.
|
||||||
// We don't from ../noder/stencil.go, but we do from ../walk/walk.go when we let
|
base.Fatalf("shape types have no methods %+v", t)
|
||||||
// shape types become the types of interfaces.
|
|
||||||
//base.Fatalf("shape types have no methods %+v", t)
|
|
||||||
}
|
}
|
||||||
tsym := TypeLinksym(t)
|
tsym := TypeLinksym(t)
|
||||||
// Emit a marker relocation. The linker will know the type is converted
|
// Emit a marker relocation. The linker will know the type is converted
|
||||||
|
|
|
@ -1873,7 +1873,7 @@ func (w *exportWriter) expr(n ir.Node) {
|
||||||
w.op(ir.OEND)
|
w.op(ir.OEND)
|
||||||
}
|
}
|
||||||
|
|
||||||
case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
|
case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
|
||||||
n := n.(*ir.ConvExpr)
|
n := n.(*ir.ConvExpr)
|
||||||
if go117ExportTypes {
|
if go117ExportTypes {
|
||||||
w.op(n.Op())
|
w.op(n.Op())
|
||||||
|
|
|
@ -1446,7 +1446,7 @@ func (r *importReader) node() ir.Node {
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
||||||
case ir.OCONV, ir.OCONVIFACE, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
|
case ir.OCONV, ir.OCONVIFACE, ir.OCONVIDATA, ir.OCONVNOP, ir.OBYTES2STR, ir.ORUNES2STR, ir.OSTR2BYTES, ir.OSTR2RUNES, ir.ORUNESTR, ir.OSLICE2ARRPTR:
|
||||||
if !go117ExportTypes && op != ir.OCONV {
|
if !go117ExportTypes && op != ir.OCONV {
|
||||||
// unreachable - mapped to OCONV case by exporter
|
// unreachable - mapped to OCONV case by exporter
|
||||||
goto error
|
goto error
|
||||||
|
|
|
@ -429,6 +429,7 @@ func readsMemory(n ir.Node) bool {
|
||||||
ir.OBITNOT,
|
ir.OBITNOT,
|
||||||
ir.OCONV,
|
ir.OCONV,
|
||||||
ir.OCONVIFACE,
|
ir.OCONVIFACE,
|
||||||
|
ir.OCONVIDATA,
|
||||||
ir.OCONVNOP,
|
ir.OCONVNOP,
|
||||||
ir.ODIV,
|
ir.ODIV,
|
||||||
ir.ODOT,
|
ir.ODOT,
|
||||||
|
|
|
@ -39,14 +39,22 @@ func walkConv(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
|
||||||
return typecheck.Conv(mkcall(fn, types.Types[result], init, typecheck.Conv(n.X, types.Types[param])), n.Type())
|
return typecheck.Conv(mkcall(fn, types.Types[result], init, typecheck.Conv(n.X, types.Types[param])), n.Type())
|
||||||
}
|
}
|
||||||
|
|
||||||
// walkConvInterface walks an OCONVIFACE node.
|
// walkConvInterface walks an OCONVIFACE or OCONVIDATA node.
|
||||||
func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
|
func walkConvInterface(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
|
||||||
|
|
||||||
n.X = walkExpr(n.X, init)
|
n.X = walkExpr(n.X, init)
|
||||||
|
|
||||||
fromType := n.X.Type()
|
fromType := n.X.Type()
|
||||||
toType := n.Type()
|
toType := n.Type()
|
||||||
|
if n.Op() == ir.OCONVIDATA {
|
||||||
if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) { // skip unnamed functions (func _())
|
// Just convert to empty interface, to make it easy.
|
||||||
|
// The caller throws away the type word.
|
||||||
|
toType = types.NewInterface(types.LocalPkg, nil)
|
||||||
|
// Note: don't pass fromType to MarkTypeUsedInInterface because it is likely
|
||||||
|
// a shape type. The appropriate call to MarkTypeUsedInInterface will come
|
||||||
|
// when building the dictionary (from which the matching type word will come).
|
||||||
|
} else if !fromType.IsInterface() && !ir.IsBlank(ir.CurFunc.Nname) {
|
||||||
|
// skip unnamed functions (func _())
|
||||||
reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
|
reflectdata.MarkTypeUsedInInterface(fromType, ir.CurFunc.LSym)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -206,6 +206,13 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
|
||||||
n := n.(*ir.ConvExpr)
|
n := n.(*ir.ConvExpr)
|
||||||
return walkConvInterface(n, init)
|
return walkConvInterface(n, init)
|
||||||
|
|
||||||
|
case ir.OCONVIDATA:
|
||||||
|
n := n.(*ir.ConvExpr)
|
||||||
|
r := ir.NewUnaryExpr(n.Pos(), ir.OIDATA, walkConvInterface(n, init))
|
||||||
|
r.SetType(types.Types[types.TUNSAFEPTR])
|
||||||
|
r.SetTypecheck(1)
|
||||||
|
return r
|
||||||
|
|
||||||
case ir.OCONV, ir.OCONVNOP:
|
case ir.OCONV, ir.OCONVNOP:
|
||||||
n := n.(*ir.ConvExpr)
|
n := n.(*ir.ConvExpr)
|
||||||
return walkConv(n, init)
|
return walkConv(n, init)
|
||||||
|
|
|
@ -1156,16 +1156,20 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
|
||||||
|
|
||||||
// concrete type (not interface) argument might need an addressable
|
// concrete type (not interface) argument might need an addressable
|
||||||
// temporary to pass to the runtime conversion routine.
|
// temporary to pass to the runtime conversion routine.
|
||||||
case ir.OCONVIFACE:
|
case ir.OCONVIFACE, ir.OCONVIDATA:
|
||||||
n := n.(*ir.ConvExpr)
|
n := n.(*ir.ConvExpr)
|
||||||
n.X = o.expr(n.X, nil)
|
n.X = o.expr(n.X, nil)
|
||||||
if n.X.Type().IsInterface() {
|
if n.X.Type().IsInterface() {
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
if _, _, needsaddr := convFuncName(n.X.Type(), n.Type()); needsaddr || isStaticCompositeLiteral(n.X) {
|
to := n.Type()
|
||||||
|
if n.Op() == ir.OCONVIDATA {
|
||||||
|
to = types.NewInterface(types.LocalPkg, nil)
|
||||||
|
}
|
||||||
|
if _, _, needsaddr := convFuncName(n.X.Type(), to); needsaddr || isStaticCompositeLiteral(n.X) {
|
||||||
// Need a temp if we need to pass the address to the conversion function.
|
// Need a temp if we need to pass the address to the conversion function.
|
||||||
// We also process static composite literal node here, making a named static global
|
// We also process static composite literal node here, making a named static global
|
||||||
// whose address we can put directly in an interface (see OCONVIFACE case in walk).
|
// whose address we can put directly in an interface (see OCONVIFACE/OCONVIDATA case in walk).
|
||||||
n.X = o.addrTemp(n.X)
|
n.X = o.addrTemp(n.X)
|
||||||
}
|
}
|
||||||
return n
|
return n
|
||||||
|
|
Loading…
Reference in a new issue