]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: simplify assert{E,I}2I{,2} calling conventions
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 17 Feb 2021 08:14:21 +0000 (15:14 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Tue, 23 Feb 2021 06:01:29 +0000 (06:01 +0000)
This CL rebases CL 273694 on top of master with @mdempsky's permission.

For assertE2I and assertI2I, there's no need to pass through the
interface's data pointer: it's always going to come back unmodified.

For assertE2I2 and assertI2I2, there's no need for an extra bool
result parameter: it's redundant with testing the returned interface
value for nil.

Change-Id: Ic92d4409ad381952f875d3d74b8cf11c32702fa6
Reviewed-on: https://go-review.googlesource.com/c/go/+/292892
Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/ssagen/ssa.go
src/cmd/compile/internal/typecheck/builtin.go
src/cmd/compile/internal/typecheck/builtin/runtime.go
src/runtime/iface.go
src/runtime/mfinal.go

index 6b1ddebd32aae2f33a9c52ea2d0039543c2499c5..e13ca90d33ffd6520f65369092594043fad07296 100644 (file)
@@ -6075,18 +6075,23 @@ func (s *state) dottype(n *ir.TypeAssertExpr, commaok bool) (res, resok *ssa.Val
                if base.Debug.TypeAssert > 0 {
                        base.WarnfAt(n.Pos(), "type assertion not inlined")
                }
-               if n.X.Type().IsEmptyInterface() {
-                       if commaok {
-                               call := s.rtcall(ir.Syms.AssertE2I2, true, []*types.Type{n.Type(), types.Types[types.TBOOL]}, target, iface)
-                               return call[0], call[1]
+               if !commaok {
+                       fn := ir.Syms.AssertI2I
+                       if n.X.Type().IsEmptyInterface() {
+                               fn = ir.Syms.AssertE2I
                        }
-                       return s.rtcall(ir.Syms.AssertE2I, true, []*types.Type{n.Type()}, target, iface)[0], nil
+                       data := s.newValue1(ssa.OpIData, types.Types[types.TUNSAFEPTR], iface)
+                       tab := s.newValue1(ssa.OpITab, byteptr, iface)
+                       tab = s.rtcall(fn, true, []*types.Type{byteptr}, target, tab)[0]
+                       return s.newValue2(ssa.OpIMake, n.Type(), tab, data), nil
                }
-               if commaok {
-                       call := s.rtcall(ir.Syms.AssertI2I2, true, []*types.Type{n.Type(), types.Types[types.TBOOL]}, target, iface)
-                       return call[0], call[1]
+               fn := ir.Syms.AssertI2I2
+               if n.X.Type().IsEmptyInterface() {
+                       fn = ir.Syms.AssertE2I2
                }
-               return s.rtcall(ir.Syms.AssertI2I, true, []*types.Type{n.Type()}, target, iface)[0], nil
+               res = s.rtcall(fn, true, []*types.Type{n.Type()}, target, iface)[0]
+               resok = s.newValue2(ssa.OpNeqInter, types.Types[types.TBOOL], res, s.constInterface(n.Type()))
+               return
        }
 
        if base.Debug.TypeAssert > 0 {
index b095a014f0cf273496f4c233a29cb60178b01277..3c7776d9ae5123c7eaf44b9a936fd8bde8b3912d 100644 (file)
@@ -80,10 +80,10 @@ var runtimeDecls = [...]struct {
        {"convT2Enoptr", funcTag, 59},
        {"convT2I", funcTag, 59},
        {"convT2Inoptr", funcTag, 59},
-       {"assertE2I", funcTag, 57},
-       {"assertE2I2", funcTag, 60},
-       {"assertI2I", funcTag, 57},
-       {"assertI2I2", funcTag, 60},
+       {"assertE2I", funcTag, 60},
+       {"assertE2I2", funcTag, 57},
+       {"assertI2I", funcTag, 60},
+       {"assertI2I2", funcTag, 57},
        {"panicdottypeE", funcTag, 61},
        {"panicdottypeI", funcTag, 61},
        {"panicnildottype", funcTag, 62},
@@ -280,7 +280,7 @@ func runtimeTypes() []*types.Type {
        typs[57] = newSig(params(typs[1], typs[2]), params(typs[2]))
        typs[58] = newSig(params(typs[2]), params(typs[7]))
        typs[59] = newSig(params(typs[1], typs[3]), params(typs[2]))
-       typs[60] = newSig(params(typs[1], typs[2]), params(typs[2], typs[6]))
+       typs[60] = newSig(params(typs[1], typs[1]), params(typs[1]))
        typs[61] = newSig(params(typs[1], typs[1], typs[1]), nil)
        typs[62] = newSig(params(typs[1]), nil)
        typs[63] = types.NewPtr(typs[5])
index ad82a9b3497a73d3c2944d5175adc99e464c4a45..d5e00afcf81bcb07d946fc46e8a7a2a7788f0cb0 100644 (file)
@@ -101,10 +101,10 @@ func convT2I(tab *byte, elem *any) (ret any)
 func convT2Inoptr(tab *byte, elem *any) (ret any)
 
 // interface type assertions x.(T)
-func assertE2I(typ *byte, iface any) (ret any)
-func assertE2I2(typ *byte, iface any) (ret any, b bool)
-func assertI2I(typ *byte, iface any) (ret any)
-func assertI2I2(typ *byte, iface any) (ret any, b bool)
+func assertE2I(inter *byte, typ *byte) *byte
+func assertE2I2(inter *byte, eface any) (ret any)
+func assertI2I(inter *byte, tab *byte) *byte
+func assertI2I2(inter *byte, iface any) (ret any)
 func panicdottypeE(have, want, iface *byte)
 func panicdottypeI(have, want, iface *byte)
 func panicnildottype(want *byte)
index 0504b89363e05efd6f6e4414a4af5e7fa7425a2b..02b18dabff2690249f06f1af5c26ab215f3843e0 100644 (file)
@@ -447,23 +447,18 @@ func convI2I(inter *interfacetype, i iface) (r iface) {
        return
 }
 
-func assertI2I(inter *interfacetype, i iface) (r iface) {
-       tab := i.tab
+func assertI2I(inter *interfacetype, tab *itab) *itab {
        if tab == nil {
                // explicit conversions require non-nil interface value.
                panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
        }
        if tab.inter == inter {
-               r.tab = tab
-               r.data = i.data
-               return
+               return tab
        }
-       r.tab = getitab(inter, tab._type, false)
-       r.data = i.data
-       return
+       return getitab(inter, tab._type, false)
 }
 
-func assertI2I2(inter *interfacetype, i iface) (r iface, b bool) {
+func assertI2I2(inter *interfacetype, i iface) (r iface) {
        tab := i.tab
        if tab == nil {
                return
@@ -476,22 +471,18 @@ func assertI2I2(inter *interfacetype, i iface) (r iface, b bool) {
        }
        r.tab = tab
        r.data = i.data
-       b = true
        return
 }
 
-func assertE2I(inter *interfacetype, e eface) (r iface) {
-       t := e._type
+func assertE2I(inter *interfacetype, t *_type) *itab {
        if t == nil {
                // explicit conversions require non-nil interface value.
                panic(&TypeAssertionError{nil, nil, &inter.typ, ""})
        }
-       r.tab = getitab(inter, t, false)
-       r.data = e.data
-       return
+       return getitab(inter, t, false)
 }
 
-func assertE2I2(inter *interfacetype, e eface) (r iface, b bool) {
+func assertE2I2(inter *interfacetype, e eface) (r iface) {
        t := e._type
        if t == nil {
                return
@@ -502,18 +493,17 @@ func assertE2I2(inter *interfacetype, e eface) (r iface, b bool) {
        }
        r.tab = tab
        r.data = e.data
-       b = true
        return
 }
 
 //go:linkname reflect_ifaceE2I reflect.ifaceE2I
 func reflect_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
-       *dst = assertE2I(inter, e)
+       *dst = iface{assertE2I(inter, e._type), e.data}
 }
 
 //go:linkname reflectlite_ifaceE2I internal/reflectlite.ifaceE2I
 func reflectlite_ifaceE2I(inter *interfacetype, e eface, dst *iface) {
-       *dst = assertE2I(inter, e)
+       *dst = iface{assertE2I(inter, e._type), e.data}
 }
 
 func iterate_itabs(fn func(*itab)) {
index 7d0313be1202691809651ae2dc967cb4b747b892..e92ec80e3c3ea85a9f78ea088f91f7e356944835 100644 (file)
@@ -214,7 +214,7 @@ func runfinq() {
                                        if len(ityp.mhdr) != 0 {
                                                // convert to interface with methods
                                                // this conversion is guaranteed to succeed - we checked in SetFinalizer
-                                               *(*iface)(frame) = assertE2I(ityp, *(*eface)(frame))
+                                               (*iface)(frame).tab = assertE2I(ityp, (*eface)(frame)._type)
                                        }
                                default:
                                        throw("bad kind in runfinq")
@@ -403,7 +403,7 @@ func SetFinalizer(obj interface{}, finalizer interface{}) {
                        // ok - satisfies empty interface
                        goto okarg
                }
-               if _, ok := assertE2I2(ityp, *efaceOf(&obj)); ok {
+               if iface := assertE2I2(ityp, *efaceOf(&obj)); iface.tab != nil {
                        goto okarg
                }
        }