mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
cmd/gc: rewrite argtype to substitute in a single pass
Substituting in multiple passes meant walking the type multiple times, and worse, if a complex type was substituted in an early pass, later passes would follow it, possibly recursively, until hitting the depth 10 limit. Change-Id: Ie61d6ec08438e297baabe932afe33d08f358e55f Reviewed-on: https://go-review.googlesource.com/7625 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Reviewed-by: Rob Pike <r@golang.org>
This commit is contained in:
parent
5fca39967d
commit
13f9c8b08e
4 changed files with 75 additions and 114 deletions
|
|
@ -311,14 +311,12 @@ func walkrange(n *Node) {
|
||||||
|
|
||||||
fn := syslook("mapiterinit", 1)
|
fn := syslook("mapiterinit", 1)
|
||||||
|
|
||||||
argtype(fn, t.Down)
|
substArgTypes(fn, t.Down, t.Type, th)
|
||||||
argtype(fn, t.Type)
|
|
||||||
argtype(fn, th)
|
|
||||||
init = list(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
|
init = list(init, mkcall1(fn, nil, nil, typename(t), ha, Nod(OADDR, hit, nil)))
|
||||||
n.Ntest = Nod(ONE, Nod(ODOT, hit, keyname), nodnil())
|
n.Ntest = Nod(ONE, Nod(ODOT, hit, keyname), nodnil())
|
||||||
|
|
||||||
fn = syslook("mapiternext", 1)
|
fn = syslook("mapiternext", 1)
|
||||||
argtype(fn, th)
|
substArgTypes(fn, th)
|
||||||
n.Nincr = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
|
n.Nincr = mkcall1(fn, nil, nil, Nod(OADDR, hit, nil))
|
||||||
|
|
||||||
key := Nod(ODOT, hit, keyname)
|
key := Nod(ODOT, hit, keyname)
|
||||||
|
|
|
||||||
|
|
@ -1369,66 +1369,57 @@ func assignconv(n *Node, t *Type, context string) *Node {
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func subtype(stp **Type, t *Type, d int) bool {
|
// substArgTypes substitutes the given list of types for
|
||||||
loop:
|
// successive occurrences of the "any" placeholder in the
|
||||||
st := *stp
|
// type syntax expression n.Type.
|
||||||
if st == nil {
|
func substArgTypes(n *Node, types ...*Type) {
|
||||||
return false
|
for _, t := range types {
|
||||||
|
dowidth(t)
|
||||||
|
}
|
||||||
|
substAny(&n.Type, &types)
|
||||||
|
if len(types) > 0 {
|
||||||
|
Fatal("substArgTypes: too many argument types")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
if t.Etype == TANY && t.Copyany != 0 {
|
||||||
|
if len(*types) == 0 {
|
||||||
|
Fatal("substArgTypes: not enough argument types")
|
||||||
|
}
|
||||||
|
*tp = (*types)[0]
|
||||||
|
*types = (*types)[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
d++
|
switch t.Etype {
|
||||||
if d >= 10 {
|
case TPTR32, TPTR64, TCHAN, TARRAY:
|
||||||
return false
|
tp = &t.Type
|
||||||
}
|
continue
|
||||||
|
|
||||||
switch st.Etype {
|
|
||||||
default:
|
|
||||||
return false
|
|
||||||
|
|
||||||
case TPTR32,
|
|
||||||
TPTR64,
|
|
||||||
TCHAN,
|
|
||||||
TARRAY:
|
|
||||||
stp = &st.Type
|
|
||||||
goto loop
|
|
||||||
|
|
||||||
case TANY:
|
|
||||||
if st.Copyany == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
*stp = t
|
|
||||||
|
|
||||||
case TMAP:
|
case TMAP:
|
||||||
if subtype(&st.Down, t, d) {
|
substAny(&t.Down, types)
|
||||||
break
|
tp = &t.Type
|
||||||
}
|
continue
|
||||||
stp = &st.Type
|
|
||||||
goto loop
|
|
||||||
|
|
||||||
case TFUNC:
|
case TFUNC:
|
||||||
for {
|
substAny(&t.Type, types)
|
||||||
if subtype(&st.Type, t, d) {
|
substAny(&t.Type.Down.Down, types)
|
||||||
break
|
substAny(&t.Type.Down, types)
|
||||||
}
|
|
||||||
if subtype(&st.Type.Down.Down, t, d) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if subtype(&st.Type.Down, t, d) {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
case TSTRUCT:
|
case TSTRUCT:
|
||||||
for st = st.Type; st != nil; st = st.Down {
|
for t = t.Type; t != nil; t = t.Down {
|
||||||
if subtype(&st.Type, t, d) {
|
substAny(&t.Type, types)
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -1484,13 +1475,6 @@ func Noconv(t1 *Type, t2 *Type) bool {
|
||||||
return false
|
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 {
|
func shallow(t *Type) *Type {
|
||||||
if t == nil {
|
if t == nil {
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -2793,18 +2777,13 @@ func eqmemfunc(size int64, type_ *Type, needsize *int) *Node {
|
||||||
fn = syslook("memequal", 1)
|
fn = syslook("memequal", 1)
|
||||||
*needsize = 1
|
*needsize = 1
|
||||||
|
|
||||||
case 1,
|
case 1, 2, 4, 8, 16:
|
||||||
2,
|
|
||||||
4,
|
|
||||||
8,
|
|
||||||
16:
|
|
||||||
buf := fmt.Sprintf("memequal%d", int(size)*8)
|
buf := fmt.Sprintf("memequal%d", int(size)*8)
|
||||||
fn = syslook(buf, 1)
|
fn = syslook(buf, 1)
|
||||||
*needsize = 0
|
*needsize = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
argtype(fn, type_)
|
substArgTypes(fn, type_, type_)
|
||||||
argtype(fn, type_)
|
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -543,7 +543,7 @@ func (s *typeSwitch) walk(sw *Node) {
|
||||||
} else {
|
} else {
|
||||||
a = syslook("ifacethash", 1)
|
a = syslook("ifacethash", 1)
|
||||||
}
|
}
|
||||||
argtype(a, t)
|
substArgTypes(a, t)
|
||||||
a = Nod(OCALL, a, nil)
|
a = Nod(OCALL, a, nil)
|
||||||
a.List = list1(s.facename)
|
a.List = list1(s.facename)
|
||||||
a = Nod(OAS, s.hashname, a)
|
a = Nod(OAS, s.hashname, a)
|
||||||
|
|
|
||||||
|
|
@ -693,8 +693,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
buf := fmt.Sprintf("assert%s2%s", from, to)
|
buf := fmt.Sprintf("assert%s2%s", from, to)
|
||||||
|
|
||||||
fn := syslook(buf, 1)
|
fn := syslook(buf, 1)
|
||||||
argtype(fn, r.Left.Type)
|
substArgTypes(fn, r.Left.Type, r.Type)
|
||||||
argtype(fn, r.Type)
|
|
||||||
|
|
||||||
n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1)
|
n = mkcall1(fn, nil, init, typename(r.Type), r.Left, n1)
|
||||||
walkexpr(&n, init)
|
walkexpr(&n, init)
|
||||||
|
|
@ -896,8 +895,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
buf := fmt.Sprintf("assert%s2%s2", from, to)
|
buf := fmt.Sprintf("assert%s2%s2", from, to)
|
||||||
|
|
||||||
fn := syslook(buf, 1)
|
fn := syslook(buf, 1)
|
||||||
argtype(fn, r.Left.Type)
|
substArgTypes(fn, r.Left.Type, r.Type)
|
||||||
argtype(fn, r.Type)
|
|
||||||
|
|
||||||
t := Types[TBOOL]
|
t := Types[TBOOL]
|
||||||
ok := n.List.Next.N
|
ok := n.List.Next.N
|
||||||
|
|
@ -1020,8 +1018,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
argtype(fn, n.Left.Type)
|
substArgTypes(fn, n.Left.Type, n.Type)
|
||||||
argtype(fn, n.Type)
|
|
||||||
dowidth(fn.Type)
|
dowidth(fn.Type)
|
||||||
n = Nod(OCALL, fn, nil)
|
n = Nod(OCALL, fn, nil)
|
||||||
n.List = ll
|
n.List = ll
|
||||||
|
|
@ -1386,7 +1383,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
case OCLOSE:
|
case OCLOSE:
|
||||||
fn := syslook("closechan", 1)
|
fn := syslook("closechan", 1)
|
||||||
|
|
||||||
argtype(fn, n.Left.Type)
|
substArgTypes(fn, n.Left.Type)
|
||||||
n = mkcall1(fn, nil, init, n.Left)
|
n = mkcall1(fn, nil, init, n.Left)
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
|
|
@ -1421,10 +1418,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
r = Nod(OADDR, var_, nil)
|
r = Nod(OADDR, var_, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
argtype(fn, hmap(t)) // hmap buffer
|
substArgTypes(fn, hmap(t), mapbucket(t), t.Down, t.Type)
|
||||||
argtype(fn, mapbucket(t)) // bucket buffer
|
|
||||||
argtype(fn, t.Down) // key type
|
|
||||||
argtype(fn, t.Type) // value type
|
|
||||||
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
|
n = mkcall1(fn, n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]), a, r)
|
||||||
goto ret
|
goto ret
|
||||||
|
|
||||||
|
|
@ -1453,7 +1447,7 @@ func walkexpr(np **Node, init **NodeList) {
|
||||||
// makeslice(t *Type, nel int64, max int64) (ary []any)
|
// makeslice(t *Type, nel int64, max int64) (ary []any)
|
||||||
fn := syslook("makeslice", 1)
|
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]))
|
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.Right = cheapexpr(n.Right, init)
|
||||||
n.Left = cheapexpr(n.Left, init)
|
n.Left = cheapexpr(n.Left, init)
|
||||||
argtype(fn, n.Right.Type)
|
substArgTypes(fn, n.Right.Type, n.Left.Type)
|
||||||
argtype(fn, n.Left.Type)
|
|
||||||
r := mkcall1(fn, n.Type, init, n.Left, n.Right)
|
r := mkcall1(fn, n.Type, init, n.Left, n.Right)
|
||||||
if n.Etype == ONE {
|
if n.Etype == ONE {
|
||||||
r = Nod(ONOT, r, nil)
|
r = Nod(ONOT, r, nil)
|
||||||
|
|
@ -2005,13 +1998,13 @@ func walkprint(nn *Node, init **NodeList) *Node {
|
||||||
} else {
|
} else {
|
||||||
on = syslook("printiface", 1)
|
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 {
|
} else if Isptr[et] || et == TCHAN || et == TMAP || et == TFUNC || et == TUNSAFEPTR {
|
||||||
on = syslook("printpointer", 1)
|
on = syslook("printpointer", 1)
|
||||||
argtype(on, n.Type) // any-1
|
substArgTypes(on, n.Type) // any-1
|
||||||
} else if Isslice(n.Type) {
|
} else if Isslice(n.Type) {
|
||||||
on = syslook("printslice", 1)
|
on = syslook("printslice", 1)
|
||||||
argtype(on, n.Type) // any-1
|
substArgTypes(on, n.Type) // any-1
|
||||||
} else if Isint[et] {
|
} else if Isint[et] {
|
||||||
if et == TUINT64 {
|
if et == TUINT64 {
|
||||||
if (t.Sym.Pkg == Runtimepkg || compiling_runtime != 0) && t.Sym.Name == "hex" {
|
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 {
|
func callnew(t *Type) *Node {
|
||||||
dowidth(t)
|
dowidth(t)
|
||||||
fn := syslook("newobject", 1)
|
fn := syslook("newobject", 1)
|
||||||
argtype(fn, t)
|
substArgTypes(fn, t)
|
||||||
return mkcall1(fn, Ptrto(t), nil, typename(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))
|
Fatal("chanfn %v", Tconv(t, 0))
|
||||||
}
|
}
|
||||||
fn := syslook(name, 1)
|
fn := syslook(name, 1)
|
||||||
for i := 0; i < n; i++ {
|
switch n {
|
||||||
argtype(fn, t.Type)
|
default:
|
||||||
|
Fatal("chanfn %d", n)
|
||||||
|
case 1:
|
||||||
|
substArgTypes(fn, t.Type)
|
||||||
|
case 2:
|
||||||
|
substArgTypes(fn, t.Type, t.Type)
|
||||||
}
|
}
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
@ -2825,10 +2823,7 @@ func mapfn(name string, t *Type) *Node {
|
||||||
Fatal("mapfn %v", Tconv(t, 0))
|
Fatal("mapfn %v", Tconv(t, 0))
|
||||||
}
|
}
|
||||||
fn := syslook(name, 1)
|
fn := syslook(name, 1)
|
||||||
argtype(fn, t.Down)
|
substArgTypes(fn, t.Down, t.Type, t.Down, t.Type)
|
||||||
argtype(fn, t.Type)
|
|
||||||
argtype(fn, t.Down)
|
|
||||||
argtype(fn, t.Type)
|
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2837,16 +2832,13 @@ func mapfndel(name string, t *Type) *Node {
|
||||||
Fatal("mapfn %v", Tconv(t, 0))
|
Fatal("mapfn %v", Tconv(t, 0))
|
||||||
}
|
}
|
||||||
fn := syslook(name, 1)
|
fn := syslook(name, 1)
|
||||||
argtype(fn, t.Down)
|
substArgTypes(fn, t.Down, t.Type, t.Down)
|
||||||
argtype(fn, t.Type)
|
|
||||||
argtype(fn, t.Down)
|
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
func writebarrierfn(name string, l *Type, r *Type) *Node {
|
func writebarrierfn(name string, l *Type, r *Type) *Node {
|
||||||
fn := syslook(name, 1)
|
fn := syslook(name, 1)
|
||||||
argtype(fn, l)
|
substArgTypes(fn, l, r)
|
||||||
argtype(fn, r)
|
|
||||||
return fn
|
return fn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2953,8 +2945,7 @@ func appendslice(n *Node, init **NodeList) *Node {
|
||||||
|
|
||||||
// instantiate growslice(Type*, []any, int) []any
|
// instantiate growslice(Type*, []any, int) []any
|
||||||
fn := syslook("growslice", 1) // growslice(<type>, old []T, n int64) (ret []T)
|
fn := syslook("growslice", 1) // growslice(<type>, old []T, n int64) (ret []T)
|
||||||
argtype(fn, s.Type.Type) // 1 old []any
|
substArgTypes(fn, s.Type.Type, s.Type.Type)
|
||||||
argtype(fn, s.Type.Type) // 2 ret []any
|
|
||||||
|
|
||||||
// s = growslice(T, s, n)
|
// s = growslice(T, s, n)
|
||||||
nif.Nbody = list1(Nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type), s, nt)))
|
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
|
nptr1.Etype = 1
|
||||||
nptr2 := l2
|
nptr2 := l2
|
||||||
fn := syslook("typedslicecopy", 1)
|
fn := syslook("typedslicecopy", 1)
|
||||||
argtype(fn, l1.Type)
|
substArgTypes(fn, l1.Type, l2.Type)
|
||||||
argtype(fn, l2.Type)
|
|
||||||
nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2)
|
nt := mkcall1(fn, Types[TINT], &l, typename(l1.Type.Type), nptr1, nptr2)
|
||||||
l = list(l, nt)
|
l = list(l, nt)
|
||||||
} else if flag_race != 0 {
|
} else if flag_race != 0 {
|
||||||
|
|
@ -2985,8 +2975,7 @@ func appendslice(n *Node, init **NodeList) *Node {
|
||||||
} else {
|
} else {
|
||||||
fn = syslook("slicecopy", 1)
|
fn = syslook("slicecopy", 1)
|
||||||
}
|
}
|
||||||
argtype(fn, l1.Type)
|
substArgTypes(fn, l1.Type, l2.Type)
|
||||||
argtype(fn, l2.Type)
|
|
||||||
nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width))
|
nt := mkcall1(fn, Types[TINT], &l, nptr1, nptr2, Nodintconst(s.Type.Type.Width))
|
||||||
l = list(l, nt)
|
l = list(l, nt)
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -2999,8 +2988,7 @@ func appendslice(n *Node, init **NodeList) *Node {
|
||||||
nptr2 := Nod(OSPTR, l2, nil)
|
nptr2 := Nod(OSPTR, l2, nil)
|
||||||
|
|
||||||
fn := syslook("memmove", 1)
|
fn := syslook("memmove", 1)
|
||||||
argtype(fn, s.Type.Type) // 1 old []any
|
substArgTypes(fn, s.Type.Type, s.Type.Type)
|
||||||
argtype(fn, s.Type.Type) // 2 ret []any
|
|
||||||
|
|
||||||
nwid := cheapexpr(conv(Nod(OLEN, l2, nil), Types[TUINTPTR]), &l)
|
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)
|
nx.Ntest = Nod(OLT, Nod(OSUB, Nod(OCAP, ns, nil), Nod(OLEN, ns, nil)), na)
|
||||||
|
|
||||||
fn := syslook("growslice", 1) // growslice(<type>, old []T, n int) (ret []T)
|
fn := syslook("growslice", 1) // growslice(<type>, old []T, n int) (ret []T)
|
||||||
argtype(fn, ns.Type.Type) // 1 old []any
|
substArgTypes(fn, ns.Type.Type, ns.Type.Type)
|
||||||
argtype(fn, ns.Type.Type) // 2 ret []any
|
|
||||||
|
|
||||||
nx.Nbody = list1(Nod(OAS, ns, mkcall1(fn, ns.Type, &nx.Ninit, typename(ns.Type), ns, na)))
|
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 {
|
} else {
|
||||||
fn = syslook("slicecopy", 1)
|
fn = syslook("slicecopy", 1)
|
||||||
}
|
}
|
||||||
argtype(fn, n.Left.Type)
|
substArgTypes(fn, n.Left.Type, n.Right.Type)
|
||||||
argtype(fn, n.Right.Type)
|
|
||||||
return mkcall1(fn, n.Type, init, n.Left, n.Right, Nodintconst(n.Left.Type.Type.Width))
|
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.
|
// Call memmove.
|
||||||
fn := syslook("memmove", 1)
|
fn := syslook("memmove", 1)
|
||||||
|
|
||||||
argtype(fn, nl.Type.Type)
|
substArgTypes(fn, nl.Type.Type, nl.Type.Type)
|
||||||
argtype(fn, nl.Type.Type)
|
|
||||||
nwid := temp(Types[TUINTPTR])
|
nwid := temp(Types[TUINTPTR])
|
||||||
l = list(l, Nod(OAS, nwid, conv(nlen, Types[TUINTPTR])))
|
l = list(l, Nod(OAS, nwid, conv(nlen, Types[TUINTPTR])))
|
||||||
nwid = Nod(OMUL, nwid, Nodintconst(nl.Type.Type.Width))
|
nwid = Nod(OMUL, nwid, Nodintconst(nl.Type.Type.Width))
|
||||||
|
|
@ -3385,8 +3370,7 @@ func eqfor(t *Type, needsize *int) *Node {
|
||||||
|
|
||||||
if a == AMEM {
|
if a == AMEM {
|
||||||
n := syslook("memequal", 1)
|
n := syslook("memequal", 1)
|
||||||
argtype(n, t)
|
substArgTypes(n, t, t)
|
||||||
argtype(n, t)
|
|
||||||
*needsize = 1
|
*needsize = 1
|
||||||
return n
|
return n
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue