]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.unified] cmd/compile: write RTTI into unified IR export data
authorMatthew Dempsky <mdempsky@google.com>
Sat, 23 Jul 2022 06:33:30 +0000 (23:33 -0700)
committerMatthew Dempsky <mdempsky@google.com>
Thu, 28 Jul 2022 07:13:28 +0000 (07:13 +0000)
This CL adds `rtype` methods for unified IR for writing/reading types
that need to have their *runtime._type value available.

For now, this just builds on the existing type writing/reading
mechanics and calling reflectdata.TypePtrAt; but longer term, reading
of derived types can be changed to use dictionary lookups instead.

Change-Id: I6f803b84546fa7df2877a8a3bcbf2623e4b03449
Reviewed-on: https://go-review.googlesource.com/c/go/+/419456
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/noder/reader.go
src/cmd/compile/internal/noder/writer.go
src/internal/pkgbits/sync.go

index 6b7ac5494f3037c0e4bb2a07f59d5dd658145130..6692446792d5a4e46c89d1407f95586cc46ed945 100644 (file)
@@ -1390,17 +1390,10 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
 
        if r.Bool() {
                pos := r.pos()
+               rang := ir.NewRangeStmt(pos, nil, nil, nil, nil)
+               rang.Label = label
 
                names, lhs := r.assignList()
-               x := r.expr()
-
-               body := r.blockStmt()
-               r.closeAnotherScope()
-
-               rang := ir.NewRangeStmt(pos, nil, nil, x, body)
-               if x.Type().IsMap() {
-                       rang.RType = reflectdata.TypePtrAt(pos, x.Type())
-               }
                if len(lhs) >= 1 {
                        rang.Key = lhs[0]
                        if len(lhs) >= 2 {
@@ -1408,10 +1401,13 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
                        }
                }
                rang.Def = r.initDefn(rang, names)
-               rang.Label = label
 
+               rang.X = r.expr()
+               if rang.X.Type().IsMap() {
+                       rang.RType = r.rtype(pos)
+               }
                {
-                       keyType, valueType := rangeTypes(pos, x.Type())
+                       keyType, valueType := rangeTypes(pos, rang.X.Type())
 
                        if rang.Key != nil {
                                rang.KeyTypeWord, rang.KeySrcRType = convRTTI(pos, rang.Key.Type(), keyType)
@@ -1421,6 +1417,9 @@ func (r *reader) forStmt(label *types.Sym) ir.Node {
                        }
                }
 
+               rang.Body = r.blockStmt()
+               r.closeAnotherScope()
+
                return rang
        }
 
@@ -1741,7 +1740,7 @@ func (r *reader) expr() (res ir.Node) {
                switch n.Op() {
                case ir.OINDEXMAP:
                        n := n.(*ir.IndexExpr)
-                       n.RType = reflectdata.TypePtrAt(pos, x.Type())
+                       n.RType = r.rtype(pos)
                }
                return n
 
@@ -1762,10 +1761,12 @@ func (r *reader) expr() (res ir.Node) {
                x := r.expr()
                pos := r.pos()
                typ := r.exprType(false)
+               srcRType := r.rtype(pos)
 
+               // TODO(mdempsky): Always emit ODYNAMICDOTTYPE for uniformity?
                if typ, ok := typ.(*ir.DynamicType); ok && typ.Op() == ir.ODYNAMICTYPE {
                        assert := ir.NewDynamicTypeAssertExpr(pos, ir.ODYNAMICDOTTYPE, x, typ.RType)
-                       assert.SrcRType = reflectdata.TypePtrAt(pos, x.Type())
+                       assert.SrcRType = srcRType
                        assert.ITab = typ.ITab
                        return typed(typ.Type(), assert)
                }
@@ -1810,16 +1811,16 @@ func (r *reader) expr() (res ir.Node) {
                switch n.Op() {
                case ir.OAPPEND:
                        n := n.(*ir.CallExpr)
-                       n.RType = reflectdata.TypePtrAt(pos, n.Type().Elem())
+                       n.RType = r.rtype(pos)
                case ir.OCOPY:
                        n := n.(*ir.BinaryExpr)
-                       n.RType = reflectdata.TypePtrAt(pos, n.X.Type().Elem())
+                       n.RType = r.rtype(pos)
                case ir.ODELETE:
                        n := n.(*ir.CallExpr)
-                       n.RType = reflectdata.TypePtrAt(pos, n.Args[0].Type())
+                       n.RType = r.rtype(pos)
                case ir.OUNSAFESLICE:
                        n := n.(*ir.BinaryExpr)
-                       n.RType = reflectdata.TypePtrAt(pos, n.Type().Elem())
+                       n.RType = r.rtype(pos)
                }
                return n
 
@@ -1828,14 +1829,7 @@ func (r *reader) expr() (res ir.Node) {
                typ := r.exprType(false)
                extra := r.exprs()
                n := typecheck.Expr(ir.NewCallExpr(pos, ir.OMAKE, nil, append([]ir.Node{typ}, extra...))).(*ir.MakeExpr)
-               switch n.Op() {
-               case ir.OMAKECHAN:
-                       n.RType = reflectdata.TypePtrAt(pos, typ.Type())
-               case ir.OMAKEMAP:
-                       n.RType = reflectdata.TypePtrAt(pos, typ.Type())
-               case ir.OMAKESLICE:
-                       n.RType = reflectdata.TypePtrAt(pos, typ.Type().Elem())
-               }
+               n.RType = r.rtype(pos)
                return n
 
        case exprNew:
@@ -1969,6 +1963,10 @@ func (r *reader) compLit() ir.Node {
        if typ.Kind() == types.TFORW {
                base.FatalfAt(pos, "unresolved composite literal type: %v", typ)
        }
+       var rtype ir.Node
+       if typ.IsMap() {
+               rtype = r.rtype(pos)
+       }
        isStruct := typ.Kind() == types.TSTRUCT
 
        elems := make([]ir.Node, r.Len())
@@ -1987,10 +1985,9 @@ func (r *reader) compLit() ir.Node {
        }
 
        lit := typecheck.Expr(ir.NewCompLitExpr(pos, ir.OCOMPLIT, typ, elems))
-       switch lit.Op() {
-       case ir.OMAPLIT:
+       if rtype != nil {
                lit := lit.(*ir.CompLitExpr)
-               lit.RType = reflectdata.TypePtrAt(pos, typ)
+               lit.RType = rtype
        }
        if typ0.IsPtr() {
                lit = typecheck.Expr(typecheck.NodAddrAt(pos, lit))
@@ -2060,6 +2057,12 @@ func (r *reader) exprs() []ir.Node {
        return nodes
 }
 
+func (r *reader) rtype(pos src.XPos) ir.Node {
+       r.Sync(pkgbits.SyncRType)
+       // TODO(mdempsky): For derived types, use dictionary instead.
+       return reflectdata.TypePtrAt(pos, r.typ())
+}
+
 func (r *reader) exprType(nilOK bool) ir.Node {
        r.Sync(pkgbits.SyncExprType)
 
index 93e81bdc821ca5fac4cf8fb5a8d0bdda10fba48b..5dd252a2a5a59b1d85170b677147015d860aa1e7 100644 (file)
@@ -1299,6 +1299,11 @@ func (w *writer) forStmt(stmt *syntax.ForStmt) {
                w.pos(rang)
                w.assignList(rang.Lhs)
                w.expr(rang.X)
+
+               xtyp := w.p.typeOf(rang.X)
+               if _, isMap := types2.CoreType(xtyp).(*types2.Map); isMap {
+                       w.rtype(xtyp)
+               }
        } else {
                w.pos(stmt)
                w.stmt(stmt.Init)
@@ -1549,8 +1554,10 @@ func (w *writer) expr(expr syntax.Expr) {
        case *syntax.IndexExpr:
                _ = w.p.typeOf(expr.Index) // ensure this is an index expression, not an instantiation
 
+               xtyp := w.p.typeOf(expr.X)
+
                var keyType types2.Type
-               if mapType, ok := types2.CoreType(w.p.typeOf(expr.X)).(*types2.Map); ok {
+               if mapType, ok := types2.CoreType(xtyp).(*types2.Map); ok {
                        keyType = mapType.Key()
                }
 
@@ -1558,6 +1565,9 @@ func (w *writer) expr(expr syntax.Expr) {
                w.expr(expr.X)
                w.pos(expr)
                w.implicitConvExpr(expr, keyType, expr.Index)
+               if keyType != nil {
+                       w.rtype(xtyp)
+               }
 
        case *syntax.SliceExpr:
                w.Code(exprSlice)
@@ -1574,6 +1584,7 @@ func (w *writer) expr(expr syntax.Expr) {
                w.expr(expr.X)
                w.pos(expr)
                w.exprType(iface, expr.Type, false)
+               w.rtype(iface)
 
        case *syntax.Operation:
                if expr.Y == nil {
@@ -1622,8 +1633,9 @@ func (w *writer) expr(expr syntax.Expr) {
                        break
                }
 
-               if name, ok := unparen(expr.Fun).(*syntax.Name); ok && tv.IsBuiltin() {
-                       switch name.Value {
+               var rtype types2.Type
+               if tv.IsBuiltin() {
+                       switch obj, _ := lookupObj(w.p.info, expr.Fun); obj.Name() {
                        case "make":
                                assert(len(expr.ArgList) >= 1)
                                assert(!expr.HasDots)
@@ -1632,6 +1644,19 @@ func (w *writer) expr(expr syntax.Expr) {
                                w.pos(expr)
                                w.exprType(nil, expr.ArgList[0], false)
                                w.exprs(expr.ArgList[1:])
+
+                               typ := w.p.typeOf(expr)
+                               switch coreType := types2.CoreType(typ).(type) {
+                               default:
+                                       w.p.fatalf(expr, "unexpected core type: %v", coreType)
+                               case *types2.Chan:
+                                       w.rtype(typ)
+                               case *types2.Map:
+                                       w.rtype(typ)
+                               case *types2.Slice:
+                                       w.rtype(sliceElem(typ))
+                               }
+
                                return
 
                        case "new":
@@ -1642,6 +1667,23 @@ func (w *writer) expr(expr syntax.Expr) {
                                w.pos(expr)
                                w.exprType(nil, expr.ArgList[0], false)
                                return
+
+                       case "append":
+                               rtype = sliceElem(w.p.typeOf(expr))
+                       case "copy":
+                               typ := w.p.typeOf(expr.ArgList[0])
+                               if tuple, ok := typ.(*types2.Tuple); ok { // "copy(g())"
+                                       typ = tuple.At(0).Type()
+                               }
+                               rtype = sliceElem(typ)
+                       case "delete":
+                               typ := w.p.typeOf(expr.ArgList[0])
+                               if tuple, ok := typ.(*types2.Tuple); ok { // "delete(g())"
+                                       typ = tuple.At(0).Type()
+                               }
+                               rtype = typ
+                       case "Slice":
+                               rtype = sliceElem(w.p.typeOf(expr))
                        }
                }
 
@@ -1676,9 +1718,16 @@ func (w *writer) expr(expr syntax.Expr) {
 
                w.multiExpr(expr, paramType, expr.ArgList)
                w.Bool(expr.HasDots)
+               if rtype != nil {
+                       w.rtype(rtype)
+               }
        }
 }
 
+func sliceElem(typ types2.Type) types2.Type {
+       return types2.CoreType(typ).(*types2.Slice).Elem()
+}
+
 func (w *writer) optExpr(expr syntax.Expr) {
        if w.Bool(expr != nil) {
                w.expr(expr)
@@ -1757,12 +1806,13 @@ func (w *writer) compLit(lit *syntax.CompositeLit) {
        }
        var keyType, elemType types2.Type
        var structType *types2.Struct
-       switch typ := types2.CoreType(typ).(type) {
+       switch typ0 := typ; typ := types2.CoreType(typ).(type) {
        default:
                w.p.fatalf(lit, "unexpected composite literal type: %v", typ)
        case *types2.Array:
                elemType = typ.Elem()
        case *types2.Map:
+               w.rtype(typ0)
                keyType, elemType = typ.Key(), typ.Elem()
        case *types2.Slice:
                elemType = typ.Elem()
@@ -1833,6 +1883,11 @@ func (w *writer) exprs(exprs []syntax.Expr) {
        }
 }
 
+func (w *writer) rtype(typ types2.Type) {
+       w.Sync(pkgbits.SyncRType)
+       w.typ(typ)
+}
+
 func (w *writer) exprType(iface types2.Type, typ syntax.Expr, nilOK bool) {
        base.Assertf(iface == nil || isInterface(iface), "%v must be nil or an interface type", iface)
 
index 6a5999eb6b9220ef8a13a513ce5ce55b83fa3520..54e478d9320763fd6417293f54c95d856eec871d 100644 (file)
@@ -112,4 +112,5 @@ const (
        SyncOptLabel
 
        SyncMultiExpr
+       SyncRType
 )