]> Cypherpunks.ru repositories - gostls13.git/blobdiff - src/cmd/compile/internal/walk/expr.go
cmd/compile: use cache in front of convI2I
[gostls13.git] / src / cmd / compile / internal / walk / expr.go
index 914011d13553a8e850a13c4e41955de083d5039b..d80b02ae4886388bbb7c433deb81cbcc306f5bf7 100644 (file)
@@ -726,25 +726,30 @@ func walkDotType(n *ir.TypeAssertExpr, init *ir.Nodes) ir.Node {
                n.ITab = reflectdata.ITabAddrAt(base.Pos, n.Type(), n.X.Type())
        }
        if n.X.Type().IsInterface() && n.Type().IsInterface() && !n.Type().IsEmptyInterface() {
-               // Converting an interface to a non-empty interface. Needs a runtime call.
-               // Allocate an internal/abi.TypeAssert descriptor for that call.
-               lsym := types.LocalPkg.Lookup(fmt.Sprintf(".typeAssert.%d", typeAssertGen)).LinksymABI(obj.ABI0)
-               typeAssertGen++
-               off := 0
-               off = objw.SymPtr(lsym, off, typecheck.LookupRuntimeVar("emptyTypeAssertCache"), 0)
-               off = objw.SymPtr(lsym, off, reflectdata.TypeSym(n.Type()).Linksym(), 0)
-               off = objw.Bool(lsym, off, n.Op() == ir.ODOTTYPE2) // CanFail
-               off += types.PtrSize - 1
-               objw.Global(lsym, int32(off), obj.LOCAL)
-               // Set the type to be just a single pointer, as the cache pointer is the
-               // only one that GC needs to see.
-               lsym.Gotype = reflectdata.TypeLinksym(types.Types[types.TUINT8].PtrTo())
-
-               n.Descriptor = lsym
+               // This kind of conversion needs a runtime call. Allocate
+               // a descriptor for that call.
+               n.Descriptor = makeTypeAssertDescriptor(n.Type(), n.Op() == ir.ODOTTYPE2)
        }
        return n
 }
 
+func makeTypeAssertDescriptor(target *types.Type, canFail bool) *obj.LSym {
+       // When converting from an interface to a non-empty interface. Needs a runtime call.
+       // Allocate an internal/abi.TypeAssert descriptor for that call.
+       lsym := types.LocalPkg.Lookup(fmt.Sprintf(".typeAssert.%d", typeAssertGen)).LinksymABI(obj.ABI0)
+       typeAssertGen++
+       off := 0
+       off = objw.SymPtr(lsym, off, typecheck.LookupRuntimeVar("emptyTypeAssertCache"), 0)
+       off = objw.SymPtr(lsym, off, reflectdata.TypeSym(target).Linksym(), 0)
+       off = objw.Bool(lsym, off, canFail)
+       off += types.PtrSize - 1
+       objw.Global(lsym, int32(off), obj.LOCAL)
+       // Set the type to be just a single pointer, as the cache pointer is the
+       // only one that GC needs to see.
+       lsym.Gotype = reflectdata.TypeLinksym(types.Types[types.TUINT8].PtrTo())
+       return lsym
+}
+
 var typeAssertGen int
 
 // walkDynamicDotType walks an ODYNAMICDOTTYPE or ODYNAMICDOTTYPE2 node.