l1 := n.List.First()
l2 := n.List.Second()
- var l []*Node
+ var nodes Nodes
// var s []T
s := temp(l1.Type)
- l = append(l, nod(OAS, s, l1)) // s = l1
+ nodes.Append(nod(OAS, s, l1)) // s = l1
+
+ elemtype := s.Type.Elem()
// n := len(s) + len(l2)
nn := temp(types.Types[TINT])
- l = append(l, nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
+ nodes.Append(nod(OAS, nn, nod(OADD, nod(OLEN, s, nil), nod(OLEN, l2, nil))))
// if uint(n) > uint(cap(s))
nif := nod(OIF, nil, nil)
- nif.Left = nod(OGT, nod(OCONV, nn, nil), nod(OCONV, nod(OCAP, s, nil), nil))
- nif.Left.Left.Type = types.Types[TUINT]
- nif.Left.Right.Type = types.Types[TUINT]
+ nuint := conv(nn, types.Types[TUINT])
+ scapuint := conv(nod(OCAP, s, nil), types.Types[TUINT])
+ nif.Left = nod(OGT, nuint, scapuint)
- // instantiate growslice(Type*, []any, int) []any
+ // instantiate growslice(typ *type, []any, int) []any
fn := syslook("growslice")
- fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())
+ fn = substArgTypes(fn, elemtype, elemtype)
// s = growslice(T, s, n)
- nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(s.Type.Elem()), s, nn)))
- l = append(l, nif)
+ nif.Nbody.Set1(nod(OAS, s, mkcall1(fn, s.Type, &nif.Ninit, typename(elemtype), s, nn)))
+ nodes.Append(nif)
// s = s[:n]
nt := nod(OSLICE, s, nil)
nt.SetSliceBounds(nil, nn, nil)
- l = append(l, nod(OAS, s, nt))
+ nodes.Append(nod(OAS, s, nt))
- if l1.Type.Elem().HasHeapPointer() {
+ var ncopy *Node
+ if elemtype.HasHeapPointer() {
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
+
nptr2 := l2
+
Curfn.Func.setWBPos(n.Pos)
+
+ // instantiate typedslicecopy(typ *type, dst any, src any) int
fn := syslook("typedslicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
- var ln Nodes
- ln.Set(l)
- nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
- l = append(ln.Slice(), nt)
+ ncopy = mkcall1(fn, types.Types[TINT], &nodes, typename(elemtype), nptr1, nptr2)
+
} else if instrumenting && !compiling_runtime {
// rely on runtime to instrument copy.
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
+
nptr2 := l2
- var ln Nodes
- ln.Set(l)
- var nt *Node
if l2.Type.IsString() {
+ // instantiate func slicestringcopy(to any, fr any) int
fn := syslook("slicestringcopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
- nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2)
+ ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2)
} else {
+ // instantiate func slicecopy(to any, fr any, wid uintptr) int
fn := syslook("slicecopy")
fn = substArgTypes(fn, l1.Type, l2.Type)
- nt = mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
+ ncopy = mkcall1(fn, types.Types[TINT], &nodes, nptr1, nptr2, nodintconst(elemtype.Width))
}
- l = append(ln.Slice(), nt)
} else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
nptr1 := nod(OINDEX, s, nod(OLEN, l1, nil))
nptr1.SetBounded(true)
-
nptr1 = nod(OADDR, nptr1, nil)
nptr2 := nod(OSPTR, l2, nil)
- fn := syslook("memmove")
- fn = substArgTypes(fn, s.Type.Elem(), s.Type.Elem())
-
- var ln Nodes
- ln.Set(l)
- nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln)
+ nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &nodes)
+ nwid = nod(OMUL, nwid, nodintconst(elemtype.Width))
- nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width))
- nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid)
- l = append(ln.Slice(), nt)
+ // instantiate func memmove(to *any, frm *any, length uintptr)
+ fn := syslook("memmove")
+ fn = substArgTypes(fn, elemtype, elemtype)
+ ncopy = mkcall1(fn, nil, &nodes, nptr1, nptr2, nwid)
}
+ ln := append(nodes.Slice(), ncopy)
- typecheckslice(l, Etop)
- walkstmtlist(l)
- init.Append(l...)
+ typecheckslice(ln, Etop)
+ walkstmtlist(ln)
+ init.Append(ln...)
return s
}