diff --git a/src/cmd/internal/gc/range.go b/src/cmd/internal/gc/range.go index ca901d2bb34..979c76affba 100644 --- a/src/cmd/internal/gc/range.go +++ b/src/cmd/internal/gc/range.go @@ -311,14 +311,12 @@ func walkrange(n *Node) { fn := syslook("mapiterinit", 1) - argtype(fn, t.Down) - argtype(fn, t.Type) - argtype(fn, th) + substArgTypes(fn, t.Down, t.Type, th) init = list(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil))) n.Ntest = Nod(ONE, Nod(ODOT, hit, keyname), nodnil()) fn = syslook("mapiternext", 1) - argtype(fn, th) + substArgTypes(fn, th) n.Nincr = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil)) key := Nod(ODOT, hit, keyname) diff --git a/src/cmd/internal/gc/subr.go b/src/cmd/internal/gc/subr.go index f77d1511fce..ec4958a2f48 100644 --- a/src/cmd/internal/gc/subr.go +++ b/src/cmd/internal/gc/subr.go @@ -1369,66 +1369,57 @@ func assignconv(n *Node, t *Type, context string) *Node { return r } -func subtype(stp **Type, t *Type, d int) bool { -loop: - st := *stp - if st == nil { - return false +// substArgTypes substitutes the given list of types for +// successive occurrences of the "any" placeholder in the +// type syntax expression n.Type. +func substArgTypes(n *Node, types ...*Type) { + for _, t := range types { + dowidth(t) } - - d++ - if d >= 10 { - return false + substAny(&n.Type, &types) + if len(types) > 0 { + Fatal("substArgTypes: too many argument types") } +} - switch st.Etype { - default: - return false - - case TPTR32, - TPTR64, - TCHAN, - TARRAY: - stp = &st.Type - goto loop - - case TANY: - if st.Copyany == 0 { - return false +// substAny walks *tp, replacing instances of "any" with successive +// elements removed from types. +func substAny(tp **Type, types *[]*Type) { + for { + t := *tp + if t == nil { + return } - *stp = t - - case TMAP: - if subtype(&st.Down, t, d) { - break - } - stp = &st.Type - goto loop - - case TFUNC: - for { - if subtype(&st.Type, t, d) { - break + if t.Etype == TANY && t.Copyany != 0 { + if len(*types) == 0 { + Fatal("substArgTypes: not enough argument types") } - if subtype(&st.Type.Down.Down, t, d) { - break - } - if subtype(&st.Type.Down, t, d) { - break - } - return false + *tp = (*types)[0] + *types = (*types)[1:] } - case TSTRUCT: - for st = st.Type; st != nil; st = st.Down { - if subtype(&st.Type, t, d) { - return true + switch t.Etype { + case TPTR32, TPTR64, TCHAN, TARRAY: + tp = &t.Type + continue + + case TMAP: + substAny(&t.Down, types) + tp = &t.Type + continue + + case TFUNC: + substAny(&t.Type, types) + substAny(&t.Type.Down.Down, types) + substAny(&t.Type.Down, types) + + case TSTRUCT: + for t = t.Type; t != nil; t = t.Down { + substAny(&t.Type, types) } } - return false + return } - - return true } /* @@ -1484,13 +1475,6 @@ func Noconv(t1 *Type, t2 *Type) bool { return false } -func argtype(on *Node, t *Type) { - dowidth(t) - if !subtype(&on.Type, t, 0) { - Fatal("argtype: failed %v %v\n", Nconv(on, 0), Tconv(t, 0)) - } -} - func shallow(t *Type) *Type { if t == nil { return nil @@ -2793,18 +2777,13 @@ func eqmemfunc(size int64, type_ *Type, needsize *int) *Node { fn = syslook("memequal", 1) *needsize = 1 - case 1, - 2, - 4, - 8, - 16: + case 1, 2, 4, 8, 16: buf := fmt.Sprintf("memequal%d", int(size)*8) fn = syslook(buf, 1) *needsize = 0 } - argtype(fn, type_) - argtype(fn, type_) + substArgTypes(fn, type_, type_) return fn } diff --git a/src/cmd/internal/gc/swt.go b/src/cmd/internal/gc/swt.go index cf40ffc27f8..c1e0405fdce 100644 --- a/src/cmd/internal/gc/swt.go +++ b/src/cmd/internal/gc/swt.go @@ -543,7 +543,7 @@ func (s *typeSwitch) walk(sw *Node) { } else { a = syslook("ifacethash", 1) } - argtype(a, t) + substArgTypes(a, t) a = Nod(OCALL, a, nil) a.List = list1(s.facename) a = Nod(OAS, s.hashname, a) diff --git a/src/cmd/internal/gc/walk.go b/src/cmd/internal/gc/walk.go index 4aecd540cf7..5fe83140470 100644 --- a/src/cmd/internal/gc/walk.go +++ b/src/cmd/internal/gc/walk.go @@ -693,8 +693,7 @@ func walkexpr(np **Node, init **NodeList) { buf := fmt.Sprintf("assert%s2%s", from, to) fn := syslook(buf, 1) - argtype(fn, r.Left.Type) - argtype(fn, r.Type) + substArgTypes(fn, r.Left.Type, r.Type) n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1) walkexpr(&n, init) @@ -896,8 +895,7 @@ func walkexpr(np **Node, init **NodeList) { buf := fmt.Sprintf("assert%s2%s2", from, to) fn := syslook(buf, 1) - argtype(fn, r.Left.Type) - argtype(fn, r.Type) + substArgTypes(fn, r.Left.Type, r.Type) t := Types[TBOOL] ok := n.List.Next.N @@ -1020,8 +1018,7 @@ func walkexpr(np **Node, init **NodeList) { } } - argtype(fn, n.Left.Type) - argtype(fn, n.Type) + substArgTypes(fn, n.Left.Type, n.Type) dowidth(fn.Type) n = Nod(OCALL, fn, nil) n.List = ll @@ -1386,7 +1383,7 @@ func walkexpr(np **Node, init **NodeList) { case OCLOSE: fn := syslook("closechan", 1) - argtype(fn, n.Left.Type) + substArgTypes(fn, n.Left.Type) n = mkcall1(fn, nil, init, n.Left) goto ret @@ -1421,10 +1418,7 @@ func walkexpr(np **Node, init **NodeList) { r = Nod(OADDR, var_, nil) } - argtype(fn, hmap(t)) // hmap buffer - argtype(fn, mapbucket(t)) // bucket buffer - argtype(fn, t.Down) // key type - argtype(fn, t.Type) // value type + substArgTypes(fn, hmap(t), mapbucket(t), t.Down, t.Type) n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r) goto ret @@ -1453,7 +1447,7 @@ func walkexpr(np **Node, init **NodeList) { // makeslice(t *Type, nel int64, max int64) (ary []any) fn := syslook("makeslice", 1) - argtype(fn, t.Type) // any-1 + substArgTypes(fn, t.Type) // any-1 n = mkcall1(fn, n.Type, init, typename(n.Type), conv(l, Types[TINT64]), conv(r, Types[TINT64])) } @@ -1554,8 +1548,7 @@ func walkexpr(np **Node, init **NodeList) { n.Right = cheapexpr(n.Right, init) n.Left = cheapexpr(n.Left, init) - argtype(fn, n.Right.Type) - argtype(fn, n.Left.Type) + substArgTypes(fn, n.Right.Type, n.Left.Type) r := mkcall1(fn, n.Type, init, n.Left, n.Right) if n.Etype == ONE { r = Nod(ONOT, r, nil) @@ -2005,13 +1998,13 @@ func walkprint(nn *Node, init **NodeList) *Node { } else { on = syslook("printiface", 1) } - argtype(on, n.Type) // any-1 + substArgTypes(on, n.Type) // any-1 } else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR { on = syslook("printpointer", 1) - argtype(on, n.Type) // any-1 + substArgTypes(on, n.Type) // any-1 } else if Isslice(n.Type) { on = syslook("printslice", 1) - argtype(on, n.Type) // any-1 + substArgTypes(on, n.Type) // any-1 } else if Isint[et] { if et == TUINT64 { if (t.Sym.Pkg == Runtimepkg || compiling_runtime != 0) && t.Sym.Name == "hex" { @@ -2072,7 +2065,7 @@ func walkprint(nn *Node, init **NodeList) *Node { func callnew(t *Type) *Node { dowidth(t) fn := syslook("newobject", 1) - argtype(fn, t) + substArgTypes(fn, t) return mkcall1(fn, Ptrto(t), nil, typename(t)) } @@ -2814,8 +2807,13 @@ func chanfn(name string, n int, t *Type) *Node { Fatal("chanfn %v", Tconv(t, 0)) } fn := syslook(name, 1) - for i := 0; i < n; i++ { - argtype(fn, t.Type) + switch n { + default: + Fatal("chanfn %d", n) + case 1: + substArgTypes(fn, t.Type) + case 2: + substArgTypes(fn, t.Type, t.Type) } return fn } @@ -2825,10 +2823,7 @@ func mapfn(name string, t *Type) *Node { Fatal("mapfn %v", Tconv(t, 0)) } fn := syslook(name, 1) - argtype(fn, t.Down) - argtype(fn, t.Type) - argtype(fn, t.Down) - argtype(fn, t.Type) + substArgTypes(fn, t.Down, t.Type, t.Down, t.Type) return fn } @@ -2837,16 +2832,13 @@ func mapfndel(name string, t *Type) *Node { Fatal("mapfn %v", Tconv(t, 0)) } fn := syslook(name, 1) - argtype(fn, t.Down) - argtype(fn, t.Type) - argtype(fn, t.Down) + substArgTypes(fn, t.Down, t.Type, t.Down) return fn } func writebarrierfn(name string, l *Type, r *Type) *Node { fn := syslook(name, 1) - argtype(fn, l) - argtype(fn, r) + substArgTypes(fn, l, r) return fn } @@ -2953,8 +2945,7 @@ func appendslice(n *Node, init **NodeList) *Node { // instantiate growslice(Type*, []any, int) []any fn := syslook("growslice", 1) // growslice(, old []T, n int64) (ret []T) - argtype(fn, s.Type.Type) // 1 old []any - argtype(fn, s.Type.Type) // 2 ret []any + substArgTypes(fn, s.Type.Type, s.Type.Type) // s = growslice(T, s, n) nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt))) @@ -2968,8 +2959,7 @@ func appendslice(n *Node, init **NodeList) *Node { nptr1.Etype = 1 nptr2 := l2 fn := syslook("typedslicecopy", 1) - argtype(fn, l1.Type) - argtype(fn, l2.Type) + substArgTypes(fn, l1.Type, l2.Type) nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2) l = list(l, nt) } else if flag_race != 0 { @@ -2985,8 +2975,7 @@ func appendslice(n *Node, init **NodeList) *Node { } else { fn = syslook("slicecopy", 1) } - argtype(fn, l1.Type) - argtype(fn, l2.Type) + substArgTypes(fn, l1.Type, l2.Type) nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width)) l = list(l, nt) } else { @@ -2999,8 +2988,7 @@ func appendslice(n *Node, init **NodeList) *Node { nptr2 := Nod(OSPTR, l2, nil) fn := syslook("memmove", 1) - argtype(fn, s.Type.Type) // 1 old []any - argtype(fn, s.Type.Type) // 2 ret []any + substArgTypes(fn, s.Type.Type, s.Type.Type) nwid := cheapexpr(conv(Nod(OLEN, l2, nil), Types[TUINTPTR]), &l) @@ -3068,8 +3056,7 @@ func walkappend(n *Node, init **NodeList) *Node { nx.Ntest = Nod(OLT, Nod(OSUB, Nod(OCAP, ns, nil), Nod(OLEN, ns, nil)), na) fn := syslook("growslice", 1) // growslice(, old []T, n int) (ret []T) - argtype(fn, ns.Type.Type) // 1 old []any - argtype(fn, ns.Type.Type) // 2 ret []any + substArgTypes(fn, ns.Type.Type, ns.Type.Type) nx.Nbody = list1(Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, na))) @@ -3121,8 +3108,7 @@ func copyany(n *Node, init **NodeList, runtimecall int) *Node { } else { fn = syslook("slicecopy", 1) } - argtype(fn, n.Left.Type) - argtype(fn, n.Right.Type) + substArgTypes(fn, n.Left.Type, n.Right.Type) return mkcall1(fn, n.Type, init, n.Left, n.Right, Nodintconst(n.Left.Type.Type.Width)) } @@ -3152,8 +3138,7 @@ func copyany(n *Node, init **NodeList, runtimecall int) *Node { // Call memmove. fn := syslook("memmove", 1) - argtype(fn, nl.Type.Type) - argtype(fn, nl.Type.Type) + substArgTypes(fn, nl.Type.Type, nl.Type.Type) nwid := temp(Types[TUINTPTR]) l = list(l, Nod(OAS, nwid, conv(nlen, Types[TUINTPTR]))) nwid = Nod(OMUL, nwid, Nodintconst(nl.Type.Type.Width)) @@ -3385,8 +3370,7 @@ func eqfor(t *Type, needsize *int) *Node { if a == AMEM { n := syslook("memequal", 1) - argtype(n, t) - argtype(n, t) + substArgTypes(n, t, t) *needsize = 1 return n }