"func @\"\".stringiter2 (? string, ? int) (@\"\".retk·1 int, @\"\".retv·2 rune)\n" +
"func @\"\".slicecopy (@\"\".to·2 any, @\"\".fr·3 any, @\"\".wid·4 uintptr \"unsafe-uintptr\") (? int)\n" +
"func @\"\".slicestringcopy (@\"\".to·2 any, @\"\".fr·3 any) (? int)\n" +
- "func @\"\".typ2Itab (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte) (@\"\".ret·1 *byte)\n" +
"func @\"\".convI2E (@\"\".elem·2 any) (@\"\".ret·1 any)\n" +
"func @\"\".convI2I (@\"\".typ·2 *byte, @\"\".elem·3 any) (@\"\".ret·1 any)\n" +
"func @\"\".convT2E (@\"\".typ·2 *byte, @\"\".elem·3 *any, @\"\".buf·4 *any) (@\"\".ret·1 any)\n" +
- "func @\"\".convT2I (@\"\".typ·2 *byte, @\"\".typ2·3 *byte, @\"\".cache·4 **byte, @\"\".elem·5 *any, @\"\".buf·6 *any) (@\"\".ret·1 any)\n" +
+ "func @\"\".convT2I (@\"\".tab·2 *byte, @\"\".elem·3 *any, @\"\".buf·4 *any) (@\"\".ret·1 any)\n" +
"func @\"\".assertE2E (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n" +
"func @\"\".assertE2E2 (@\"\".typ·2 *byte, @\"\".iface·3 any, @\"\".ret·4 *any) (? bool)\n" +
"func @\"\".assertE2I (@\"\".typ·1 *byte, @\"\".iface·2 any, @\"\".ret·3 *any)\n" +
func slicestringcopy(to any, fr any) int
// interface conversions
-func typ2Itab(typ *byte, typ2 *byte, cache **byte) (ret *byte)
func convI2E(elem any) (ret any)
func convI2I(typ *byte, elem any) (ret any)
func convT2E(typ *byte, elem, buf *any) (ret any)
-func convT2I(typ *byte, typ2 *byte, cache **byte, elem, buf *any) (ret any)
+func convT2I(tab *byte, elem, buf *any) (ret any)
// interface type assertions x.(T)
func assertE2E(typ *byte, iface any, ret *any)
var importpkg *Pkg // package being imported
-var itabpkg *Pkg // fake pkg for itab cache
-
-var itab2pkg *Pkg // fake pkg for itab entries
+var itabpkg *Pkg // fake pkg for itab entries
var itablinkpkg *Pkg // fake package for runtime itab entries
// pseudo-package, for scoping
builtinpkg = mkpkg("go.builtin")
-
builtinpkg.Prefix = "go.builtin" // not go%2ebuiltin
// pseudo-package, accessed by import "unsafe"
unsafepkg = mkpkg("unsafe")
-
unsafepkg.Name = "unsafe"
// real package, referred to by generated runtime calls
Runtimepkg = mkpkg("runtime")
-
Runtimepkg.Name = "runtime"
// pseudo-packages used in symbol tables
itabpkg.Name = "go.itab"
itabpkg.Prefix = "go.itab" // not go%2eitab
- itab2pkg = mkpkg("go.itab2")
- itab2pkg.Name = "go.itab2"
- itab2pkg.Prefix = "go.itab2" // not go%2eitab2
-
typelinkpkg = mkpkg("go.typelink")
typelinkpkg.Name = "go.typelink"
typelinkpkg.Prefix = "go.typelink" // not go%2etypelink
itablinkpkg.Prefix = "go.itablink" // not go%2eitablink
trackpkg = mkpkg("go.track")
-
trackpkg.Name = "go.track"
trackpkg.Prefix = "go.track" // not go%2etrack
typepkg = mkpkg("type")
-
typepkg.Name = "type"
goroot = obj.Getgoroot()
if t == nil || (Isptr[t.Etype] && t.Type == nil) || isideal(t) {
Fatalf("itabname %v", t)
}
- s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itab2pkg)
+ s := Pkglookup(Tconv(t, FmtLeft)+","+Tconv(itype, FmtLeft), itabpkg)
if s.Def == nil {
n := newname(s)
n.Type = Types[TUINT8]
}
var ll []*Node
- if !Isinter(n.Left.Type) {
- ll = append(ll, typename(n.Left.Type))
- }
- if !isnilinter(n.Type) {
- ll = append(ll, typename(n.Type))
- }
- if !Isinter(n.Left.Type) && !isnilinter(n.Type) {
- sym := Pkglookup(Tconv(n.Left.Type, FmtLeft)+"."+Tconv(n.Type, FmtLeft), itabpkg)
- if sym.Def == nil {
- l := Nod(ONAME, nil, nil)
- l.Sym = sym
- l.Type = Ptrto(Types[TUINT8])
- l.Addable = true
- l.Class = PEXTERN
- l.Xoffset = 0
- sym.Def = l
- ggloblsym(sym, int32(Widthptr), obj.DUPOK|obj.NOPTR)
+ if isnilinter(n.Type) {
+ if !Isinter(n.Left.Type) {
+ ll = append(ll, typename(n.Left.Type))
}
-
- l := Nod(OADDR, sym.Def, nil)
- l.Addable = true
- ll = append(ll, l)
-
- if isdirectiface(n.Left.Type) {
- // For pointer types, we can make a special form of optimization
- //
- // These statements are put onto the expression init list:
- // Itab *tab = atomicloadtype(&cache);
- // if(tab == nil)
- // tab = typ2Itab(type, itype, &cache);
- //
- // The CONVIFACE expression is replaced with this:
- // OEFACE{tab, ptr};
- l := temp(Ptrto(Types[TUINT8]))
-
- n1 := Nod(OAS, l, sym.Def)
- n1 = typecheck(n1, Etop)
- init.Append(n1)
-
- fn := syslook("typ2Itab")
- n1 = Nod(OCALL, fn, nil)
- n1.List.Set(ll)
- n1 = typecheck(n1, Erv)
- n1 = walkexpr(n1, init)
-
- n2 := Nod(OIF, nil, nil)
- n2.Left = Nod(OEQ, l, nodnil())
- n2.Nbody.Set1(Nod(OAS, l, n1))
- n2.Likely = -1
- n2 = typecheck(n2, Etop)
- init.Append(n2)
-
- l = Nod(OEFACE, l, n.Left)
- l.Typecheck = n.Typecheck
- l.Type = n.Type
- n = l
- break
+ } else {
+ if Isinter(n.Left.Type) {
+ ll = append(ll, typename(n.Type))
+ } else {
+ ll = append(ll, itabname(n.Left.Type, n.Type))
}
}
unlock(&ifaceLock)
}
-func typ2Itab(t *_type, inter *interfacetype, cache **itab) *itab {
- tab := getitab(inter, t, false)
- atomicstorep(unsafe.Pointer(cache), unsafe.Pointer(tab))
- return tab
-}
-
func convT2E(t *_type, elem unsafe.Pointer, x unsafe.Pointer) (e eface) {
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2E))
return
}
-func convT2I(t *_type, inter *interfacetype, cache **itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) {
+func convT2I(tab *itab, elem unsafe.Pointer, x unsafe.Pointer) (i iface) {
+ t := tab._type
if raceenabled {
raceReadObjectPC(t, elem, getcallerpc(unsafe.Pointer(&t)), funcPC(convT2I))
}
if msanenabled {
msanread(elem, t.size)
}
- tab := (*itab)(atomic.Loadp(unsafe.Pointer(cache)))
- if tab == nil {
- tab = getitab(inter, t, false)
- atomicstorep(unsafe.Pointer(cache), unsafe.Pointer(tab))
- }
if isDirectIface(t) {
i.tab = tab
typedmemmove(t, unsafe.Pointer(&i.data), elem)