cmd/compile: factor out Pkg, Sym, and Type into package types

- created new package cmd/compile/internal/types
- moved Pkg, Sym, Type to new package
- to break cycles, for now we need the (ugly) types/utils.go
  file which contains a handful of functions that must be installed
  early by the gc frontend
- to break cycles, for now we need two functions to convert between
  *gc.Node and *types.Node (the latter is a dummy type)
- adjusted the gc's code to use the new package and the conversion
  functions as needed
- made several Pkg, Sym, and Type methods functions as needed
- renamed constructors typ, typPtr, typArray, etc. to types.New,
  types.NewPtr, types.NewArray, etc.

Passes toolstash-check -all.

Change-Id: I8adfa5e85c731645d0a7fd2030375ed6ebf54b72
Reviewed-on: https://go-review.googlesource.com/39855
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
This commit is contained in:
Robert Griesemer 2017-04-04 17:54:02 -07:00
parent 19bd145d07
commit f68f292820
48 changed files with 2433 additions and 2005 deletions

View file

@ -5,6 +5,7 @@
package gc
import (
"cmd/compile/internal/types"
"cmd/internal/obj"
"cmd/internal/sys"
"fmt"
@ -405,9 +406,9 @@ func walkexprlistcheap(s []*Node, init *Nodes) {
// Build name of function for interface conversion.
// Not all names are possible
// (e.g., we'll never generate convE2E or convE2I or convI2E).
func convFuncName(from, to *Type) string {
tkind := to.iet()
switch from.iet() {
func convFuncName(from, to *types.Type) string {
tkind := to.Tie()
switch from.Tie() {
case 'I':
switch tkind {
case 'I':
@ -419,15 +420,15 @@ func convFuncName(from, to *Type) string {
switch {
case from.Size() == 2 && from.Align == 2:
return "convT2E16"
case from.Size() == 4 && from.Align == 4 && !haspointers(from):
case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from):
return "convT2E32"
case from.Size() == 8 && from.Align == Types[TUINT64].Align && !haspointers(from):
case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from):
return "convT2E64"
case from.IsString():
return "convT2Estring"
case from.IsSlice():
return "convT2Eslice"
case !haspointers(from):
case !types.Haspointers(from):
return "convT2Enoptr"
}
return "convT2E"
@ -435,21 +436,21 @@ func convFuncName(from, to *Type) string {
switch {
case from.Size() == 2 && from.Align == 2:
return "convT2I16"
case from.Size() == 4 && from.Align == 4 && !haspointers(from):
case from.Size() == 4 && from.Align == 4 && !types.Haspointers(from):
return "convT2I32"
case from.Size() == 8 && from.Align == Types[TUINT64].Align && !haspointers(from):
case from.Size() == 8 && from.Align == types.Types[TUINT64].Align && !types.Haspointers(from):
return "convT2I64"
case from.IsString():
return "convT2Istring"
case from.IsSlice():
return "convT2Islice"
case !haspointers(from):
case !types.Haspointers(from):
return "convT2Inoptr"
}
return "convT2I"
}
}
Fatalf("unknown conv func %c2%c", from.iet(), to.iet())
Fatalf("unknown conv func %c2%c", from.Tie(), to.Tie())
panic("unreachable")
}
@ -822,7 +823,7 @@ opswitch:
// don't generate a = *var if a is _
if !isblank(a) {
var_ := temp(typPtr(t.Val()))
var_ := temp(types.NewPtr(t.Val()))
var_.Typecheck = 1
var_.SetNonNil(true) // mapaccess always returns a non-nil pointer
n.List.SetFirst(var_)
@ -874,10 +875,10 @@ opswitch:
if staticbytes == nil {
staticbytes = newname(Runtimepkg.Lookup("staticbytes"))
staticbytes.Class = PEXTERN
staticbytes.Type = typArray(Types[TUINT8], 256)
staticbytes.Type = types.NewArray(types.Types[TUINT8], 256)
zerobase = newname(Runtimepkg.Lookup("zerobase"))
zerobase.Class = PEXTERN
zerobase.Type = Types[TUINTPTR]
zerobase.Type = types.Types[TUINTPTR]
}
// Optimize convT2{E,I} for many cases in which T is not pointer-shaped,
@ -931,7 +932,7 @@ opswitch:
init.Append(nod(OAS, c, n.Left))
// Get the itab out of the interface.
tmp := temp(typPtr(Types[TUINT8]))
tmp := temp(types.NewPtr(types.Types[TUINT8]))
init.Append(nod(OAS, tmp, typecheck(nod(OITAB, c, nil), Erv)))
// Get the type out of the itab.
@ -940,7 +941,7 @@ opswitch:
init.Append(nif)
// Build the result.
e := nod(OEFACE, tmp, ifaceData(c, typPtr(Types[TUINT8])))
e := nod(OEFACE, tmp, ifaceData(c, types.NewPtr(types.Types[TUINT8])))
e.Type = n.Type // assign type manually, typecheck doesn't understand OEFACE.
e.Typecheck = 1
n = e
@ -989,24 +990,24 @@ opswitch:
if thearch.LinkArch.Family == sys.ARM || thearch.LinkArch.Family == sys.MIPS {
if n.Left.Type.IsFloat() {
if n.Type.Etype == TINT64 {
n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break
}
if n.Type.Etype == TUINT64 {
n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break
}
}
if n.Type.IsFloat() {
if n.Left.Type.Etype == TINT64 {
n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type)
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break
}
if n.Left.Type.Etype == TUINT64 {
n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type)
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break
}
}
@ -1015,31 +1016,31 @@ opswitch:
if thearch.LinkArch.Family == sys.I386 {
if n.Left.Type.IsFloat() {
if n.Type.Etype == TINT64 {
n = mkcall("float64toint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
n = mkcall("float64toint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break
}
if n.Type.Etype == TUINT64 {
n = mkcall("float64touint64", n.Type, init, conv(n.Left, Types[TFLOAT64]))
n = mkcall("float64touint64", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break
}
if n.Type.Etype == TUINT32 || n.Type.Etype == TUINT || n.Type.Etype == TUINTPTR {
n = mkcall("float64touint32", n.Type, init, conv(n.Left, Types[TFLOAT64]))
n = mkcall("float64touint32", n.Type, init, conv(n.Left, types.Types[TFLOAT64]))
break
}
}
if n.Type.IsFloat() {
if n.Left.Type.Etype == TINT64 {
n = conv(mkcall("int64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TINT64])), n.Type)
n = conv(mkcall("int64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TINT64])), n.Type)
break
}
if n.Left.Type.Etype == TUINT64 {
n = conv(mkcall("uint64tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT64])), n.Type)
n = conv(mkcall("uint64tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT64])), n.Type)
break
}
if n.Left.Type.Etype == TUINT32 || n.Left.Type.Etype == TUINT || n.Left.Type.Etype == TUINTPTR {
n = conv(mkcall("uint32tofloat64", Types[TFLOAT64], init, conv(n.Left, Types[TUINT32])), n.Type)
n = conv(mkcall("uint32tofloat64", types.Types[TFLOAT64], init, conv(n.Left, types.Types[TUINT32])), n.Type)
break
}
}
@ -1063,7 +1064,7 @@ opswitch:
if isComplex[et] && n.Op == ODIV {
t := n.Type
n = mkcall("complex128div", Types[TCOMPLEX128], init, conv(n.Left, Types[TCOMPLEX128]), conv(n.Right, Types[TCOMPLEX128]))
n = mkcall("complex128div", types.Types[TCOMPLEX128], init, conv(n.Left, types.Types[TCOMPLEX128]), conv(n.Right, types.Types[TCOMPLEX128]))
n = conv(n, t)
break
}
@ -1107,7 +1108,7 @@ opswitch:
} else {
fn += "mod"
}
n = mkcall(fn, n.Type, init, conv(n.Left, Types[et]), conv(n.Right, Types[et]))
n = mkcall(fn, n.Type, init, conv(n.Left, types.Types[et]), conv(n.Right, types.Types[et]))
}
case OINDEX:
@ -1178,13 +1179,13 @@ opswitch:
}
if w := t.Val().Width; w <= 1024 { // 1024 must match ../../../../runtime/hashmap.go:maxZero
n = mkcall1(mapfn(mapaccess1[fast], t), typPtr(t.Val()), init, typename(t), map_, key)
n = mkcall1(mapfn(mapaccess1[fast], t), types.NewPtr(t.Val()), init, typename(t), map_, key)
} else {
z := zeroaddr(w)
n = mkcall1(mapfn("mapaccess1_fat", t), typPtr(t.Val()), init, typename(t), map_, key, z)
n = mkcall1(mapfn("mapaccess1_fat", t), types.NewPtr(t.Val()), init, typename(t), map_, key, z)
}
}
n.Type = typPtr(t.Val())
n.Type = types.NewPtr(t.Val())
n.SetNonNil(true) // mapaccess1* and mapassign always return non-nil pointers.
n = nod(OIND, n, nil)
n.Type = t.Val()
@ -1303,7 +1304,7 @@ opswitch:
n.Left = cheapexpr(n.Left, init)
n.Right = cheapexpr(n.Right, init)
r = mkcall("eqstring", Types[TBOOL], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING]))
r = mkcall("eqstring", types.Types[TBOOL], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
// quick check of len before full compare for == or !=
// eqstring assumes that the lengths are equal
@ -1321,7 +1322,7 @@ opswitch:
r = walkexpr(r, nil)
} else {
// sys_cmpstring(s1, s2) :: 0
r = mkcall("cmpstring", Types[TINT], init, conv(n.Left, Types[TSTRING]), conv(n.Right, Types[TSTRING]))
r = mkcall("cmpstring", types.Types[TINT], init, conv(n.Left, types.Types[TSTRING]), conv(n.Right, types.Types[TSTRING]))
// TODO(marvin): Fix Node.EType type union.
r = nod(Op(n.Etype), r, nodintconst(0))
}
@ -1351,7 +1352,7 @@ opswitch:
n = mkcall1(fn, nil, init, n.Left)
case OMAKECHAN:
n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, Types[TINT64]))
n = mkcall1(chanfn("makechan", 1, n.Type), n.Type, init, typename(n.Type), conv(n.Left, types.Types[TINT64]))
case OMAKEMAP:
t := n.Type
@ -1380,7 +1381,7 @@ opswitch:
fn := syslook("makemap")
fn = substArgTypes(fn, hmap(t), mapbucket(t), t.Key(), t.Val())
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.Types[TINT64]), a, r)
case OMAKESLICE:
l := n.Left
@ -1396,7 +1397,7 @@ opswitch:
}
// var arr [r]T
// n = arr[:l]
t = typArray(t.Elem(), nonnegintconst(r)) // [r]T
t = types.NewArray(t.Elem(), nonnegintconst(r)) // [r]T
var_ := temp(t)
a := nod(OAS, var_, nil) // zero temp
a = typecheck(a, Etop)
@ -1419,7 +1420,7 @@ opswitch:
len, cap := l, r
fnname := "makeslice64"
argtype := Types[TINT64]
argtype := types.Types[TINT64]
// typechecking guarantees that TIDEAL len/cap are positive and fit in an int.
// The case of len or cap overflow when converting TUINT or TUINTPTR to TINT
@ -1427,7 +1428,7 @@ opswitch:
if (len.Type.IsKind(TIDEAL) || maxintval[len.Type.Etype].Cmp(maxintval[TUINT]) <= 0) &&
(cap.Type.IsKind(TIDEAL) || maxintval[cap.Type.Etype].Cmp(maxintval[TUINT]) <= 0) {
fnname = "makeslice"
argtype = Types[TINT]
argtype = types.Types[TINT]
}
fn := syslook(fnname)
@ -1438,19 +1439,19 @@ opswitch:
case ORUNESTR:
a := nodnil()
if n.Esc == EscNone {
t := typArray(Types[TUINT8], 4)
t := types.NewArray(types.Types[TUINT8], 4)
var_ := temp(t)
a = nod(OADDR, var_, nil)
}
// intstring(*[4]byte, rune)
n = mkcall("intstring", n.Type, init, a, conv(n.Left, Types[TINT64]))
n = mkcall("intstring", n.Type, init, a, conv(n.Left, types.Types[TINT64]))
case OARRAYBYTESTR:
a := nodnil()
if n.Esc == EscNone {
// Create temporary buffer for string on stack.
t := typArray(Types[TUINT8], tmpstringbufsize)
t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
a = nod(OADDR, temp(t), nil)
}
@ -1476,7 +1477,7 @@ opswitch:
if n.Esc == EscNone {
// Create temporary buffer for string on stack.
t := typArray(Types[TUINT8], tmpstringbufsize)
t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
a = nod(OADDR, temp(t), nil)
}
@ -1489,12 +1490,12 @@ opswitch:
if n.Esc == EscNone {
// Create temporary buffer for slice on stack.
t := typArray(Types[TUINT8], tmpstringbufsize)
t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
a = nod(OADDR, temp(t), nil)
}
n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, Types[TSTRING]))
n = mkcall("stringtoslicebyte", n.Type, init, a, conv(n.Left, types.Types[TSTRING]))
case OSTRARRAYBYTETMP:
// []byte(string) conversion that creates a slice
@ -1512,7 +1513,7 @@ opswitch:
if n.Esc == EscNone {
// Create temporary buffer for slice on stack.
t := typArray(Types[TINT32], tmpstringbufsize)
t := types.NewArray(types.Types[TINT32], tmpstringbufsize)
a = nod(OADDR, temp(t), nil)
}
@ -1537,8 +1538,8 @@ opswitch:
rt := nod(OITAB, n.Right, nil)
ld := nod(OIDATA, n.Left, nil)
rd := nod(OIDATA, n.Right, nil)
ld.Type = Types[TUNSAFEPTR]
rd.Type = Types[TUNSAFEPTR]
ld.Type = types.Types[TUNSAFEPTR]
rd.Type = types.Types[TUNSAFEPTR]
ld.Typecheck = 1
rd.Typecheck = 1
call := mkcall1(fn, n.Type, init, lt, ld, rd)
@ -1680,7 +1681,7 @@ func ascompatee(op Op, nl, nr []*Node, init *Nodes) []*Node {
// return 1 if this implies a function call
// evaluating the lv or a function call
// in the conversion of the types
func fncall(l *Node, rt *Type) bool {
func fncall(l *Node, rt *types.Type) bool {
if l.HasCall() || l.Op == OINDEXMAP {
return true
}
@ -1696,7 +1697,7 @@ func fncall(l *Node, rt *Type) bool {
// check assign type list to
// a expression list. called in
// expr-list = func()
func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
func ascompatet(op Op, nl Nodes, nr *types.Type) []*Node {
if nl.Len() != nr.NumFields() {
Fatalf("ascompatet: assignment count mismatch: %d = %d", nl.Len(), nr.NumFields())
}
@ -1734,7 +1735,7 @@ func ascompatet(op Op, nl Nodes, nr *Type) []*Node {
}
// package all the arguments that match a ... T parameter into a []T.
func mkdotargslice(typ *Type, args []*Node, init *Nodes, ddd *Node) *Node {
func mkdotargslice(typ *types.Type, args []*Node, init *Nodes, ddd *Node) *Node {
esc := uint16(EscUnknown)
if ddd != nil {
esc = ddd.Esc
@ -1764,7 +1765,7 @@ func mkdotargslice(typ *Type, args []*Node, init *Nodes, ddd *Node) *Node {
// a type list. called in
// return expr-list
// func(expr-list)
func ascompatte(call *Node, isddd bool, lhs *Type, rhs []*Node, fp int, init *Nodes) []*Node {
func ascompatte(call *Node, isddd bool, lhs *types.Type, rhs []*Node, fp int, init *Nodes) []*Node {
var nn []*Node
// f(g()) where g has multiple return values
@ -1824,8 +1825,8 @@ func walkprint(nn *Node, init *Nodes) *Node {
var r *Node
var n *Node
var on *Node
var t *Type
var et EType
var t *types.Type
var et types.EType
op := nn.Op
all := nn.List
@ -1847,18 +1848,18 @@ func walkprint(nn *Node, init *Nodes) *Node {
if n.Op == OLITERAL {
switch n.Val().Ctype() {
case CTRUNE:
n = defaultlit(n, runetype)
n = defaultlit(n, types.Runetype)
case CTINT:
n = defaultlit(n, Types[TINT64])
n = defaultlit(n, types.Types[TINT64])
case CTFLT:
n = defaultlit(n, Types[TFLOAT64])
n = defaultlit(n, types.Types[TFLOAT64])
}
}
if n.Op != OLITERAL && n.Type != nil && n.Type.Etype == TIDEAL {
n = defaultlit(n, Types[TINT64])
n = defaultlit(n, types.Types[TINT64])
}
n = defaultlit(n, nil)
all.SetIndex(i1, n)
@ -1883,7 +1884,7 @@ func walkprint(nn *Node, init *Nodes) *Node {
on = substArgTypes(on, n.Type) // any-1
} else if isInt[et] {
if et == TUINT64 {
if t.Sym.Pkg.isRuntime() && t.Sym.Name == "hex" {
if isRuntimePkg(t.Sym.Pkg) && t.Sym.Name == "hex" {
on = syslook("printhex")
} else {
on = syslook("printuint")
@ -1932,14 +1933,14 @@ func walkprint(nn *Node, init *Nodes) *Node {
return r
}
func callnew(t *Type) *Node {
func callnew(t *types.Type) *Node {
if t.NotInHeap() {
yyerror("%v is go:notinheap; heap allocation disallowed", t)
}
dowidth(t)
fn := syslook("newobject")
fn = substArgTypes(fn, t)
v := mkcall1(fn, typPtr(t), nil, typename(t))
v := mkcall1(fn, types.NewPtr(t), nil, typename(t))
v.SetNonNil(true)
return v
}
@ -1978,11 +1979,11 @@ func isstack(n *Node) bool {
// isReflectHeaderDataField reports whether l is an expression p.Data
// where p has type reflect.SliceHeader or reflect.StringHeader.
func isReflectHeaderDataField(l *Node) bool {
if l.Type != Types[TUINTPTR] {
if l.Type != types.Types[TUINTPTR] {
return false
}
var tsym *Sym
var tsym *types.Sym
switch l.Op {
case ODOT:
tsym = l.Left.Type.Sym
@ -2022,7 +2023,7 @@ func needwritebarrier(l *Node) bool {
// No write barrier for write of non-pointers.
dowidth(l.Type)
if !haspointers(l.Type) {
if !types.Haspointers(l.Type) {
return false
}
@ -2051,8 +2052,8 @@ func convas(n *Node, init *Nodes) *Node {
n.Typecheck = 1
var lt *Type
var rt *Type
var lt *types.Type
var rt *types.Type
if n.Left == nil || n.Right == nil {
goto out
}
@ -2436,10 +2437,10 @@ func vmatch1(l *Node, r *Node) bool {
// paramstoheap returns code to allocate memory for heap-escaped parameters
// and to copy non-result prameters' values from the stack.
func paramstoheap(params *Type) []*Node {
func paramstoheap(params *types.Type) []*Node {
var nn []*Node
for _, t := range params.Fields().Slice() {
v := t.Nname
v := asNode(t.Nname)
if v != nil && v.Sym != nil && strings.HasPrefix(v.Sym.Name, "~r") { // unnamed result
v = nil
}
@ -2469,7 +2470,7 @@ func zeroResults() {
lno := lineno
lineno = Curfn.Pos
for _, f := range Curfn.Type.Results().Fields().Slice() {
if v := f.Nname; v != nil && v.Name.Param.Heapaddr != nil {
if v := asNode(f.Nname); v != nil && v.Name.Param.Heapaddr != nil {
// The local which points to the return value is the
// thing that needs zeroing. This is already handled
// by a Needzero annotation in plive.go:livenessepilogue.
@ -2483,10 +2484,10 @@ func zeroResults() {
// returnsfromheap returns code to copy values for heap-escaped parameters
// back to the stack.
func returnsfromheap(params *Type) []*Node {
func returnsfromheap(params *types.Type) []*Node {
var nn []*Node
for _, t := range params.Fields().Slice() {
v := t.Nname
v := asNode(t.Nname)
if v == nil {
continue
}
@ -2513,7 +2514,7 @@ func heapmoves() {
lineno = lno
}
func vmkcall(fn *Node, t *Type, init *Nodes, va []*Node) *Node {
func vmkcall(fn *Node, t *types.Type, init *Nodes, va []*Node) *Node {
if fn.Type == nil || fn.Type.Etype != TFUNC {
Fatalf("mkcall %v %v", fn, fn.Type)
}
@ -2532,15 +2533,15 @@ func vmkcall(fn *Node, t *Type, init *Nodes, va []*Node) *Node {
return r
}
func mkcall(name string, t *Type, init *Nodes, args ...*Node) *Node {
func mkcall(name string, t *types.Type, init *Nodes, args ...*Node) *Node {
return vmkcall(syslook(name), t, init, args)
}
func mkcall1(fn *Node, t *Type, init *Nodes, args ...*Node) *Node {
func mkcall1(fn *Node, t *types.Type, init *Nodes, args ...*Node) *Node {
return vmkcall(fn, t, init, args)
}
func conv(n *Node, t *Type) *Node {
func conv(n *Node, t *types.Type) *Node {
if eqtype(n.Type, t) {
return n
}
@ -2554,16 +2555,16 @@ func conv(n *Node, t *Type) *Node {
// We cannot use conv, because we allow converting bool to uint8 here,
// which is forbidden in user code.
func byteindex(n *Node) *Node {
if eqtype(n.Type, Types[TUINT8]) {
if eqtype(n.Type, types.Types[TUINT8]) {
return n
}
n = nod(OCONV, n, nil)
n.Type = Types[TUINT8]
n.Type = types.Types[TUINT8]
n.Typecheck = 1
return n
}
func chanfn(name string, n int, t *Type) *Node {
func chanfn(name string, n int, t *types.Type) *Node {
if !t.IsChan() {
Fatalf("chanfn %v", t)
}
@ -2579,7 +2580,7 @@ func chanfn(name string, n int, t *Type) *Node {
return fn
}
func mapfn(name string, t *Type) *Node {
func mapfn(name string, t *types.Type) *Node {
if !t.IsMap() {
Fatalf("mapfn %v", t)
}
@ -2588,7 +2589,7 @@ func mapfn(name string, t *Type) *Node {
return fn
}
func mapfndel(name string, t *Type) *Node {
func mapfndel(name string, t *types.Type) *Node {
if !t.IsMap() {
Fatalf("mapfn %v", t)
}
@ -2616,7 +2617,7 @@ var mapaccess2 mapnames = mkmapnames("mapaccess2")
var mapassign mapnames = mkmapnames("mapassign")
var mapdelete mapnames = mkmapnames("mapdelete")
func mapfast(t *Type) int {
func mapfast(t *types.Type) int {
// Check ../../runtime/hashmap.go:maxValueSize before changing.
if t.Val().Width > 128 {
return mapslow
@ -2632,7 +2633,7 @@ func mapfast(t *Type) int {
return mapslow
}
func writebarrierfn(name string, l *Type, r *Type) *Node {
func writebarrierfn(name string, l *types.Type, r *types.Type) *Node {
fn := syslook(name)
fn = substArgTypes(fn, l, r)
return fn
@ -2658,7 +2659,7 @@ func addstr(n *Node, init *Nodes) *Node {
// Don't allocate the buffer if the result won't fit.
if sz < tmpstringbufsize {
// Create temporary buffer for result string on stack.
t := typArray(Types[TUINT8], tmpstringbufsize)
t := types.NewArray(types.Types[TUINT8], tmpstringbufsize)
buf = nod(OADDR, temp(t), nil)
}
@ -2667,7 +2668,7 @@ func addstr(n *Node, init *Nodes) *Node {
// build list of string arguments
args := []*Node{buf}
for _, n2 := range n.List.Slice() {
args = append(args, conv(n2, Types[TSTRING]))
args = append(args, conv(n2, types.Types[TSTRING]))
}
var fn string
@ -2679,7 +2680,7 @@ func addstr(n *Node, init *Nodes) *Node {
// large numbers of strings are passed to the runtime as a slice.
fn = "concatstrings"
t := typSlice(Types[TSTRING])
t := types.NewSlice(types.Types[TSTRING])
slice := nod(OCOMPLIT, nil, typenod(t))
if prealloc[n] != nil {
prealloc[slice] = prealloc[n]
@ -2734,14 +2735,14 @@ func appendslice(n *Node, init *Nodes) *Node {
l = append(l, nod(OAS, s, l1)) // s = l1
// n := len(s) + len(l2)
nn := temp(Types[TINT])
nn := temp(types.Types[TINT])
l = append(l, 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[TUINT]
nif.Left.Right.Type = Types[TUINT]
nif.Left.Left.Type = types.Types[TUINT]
nif.Left.Right.Type = types.Types[TUINT]
// instantiate growslice(Type*, []any, int) []any
fn := syslook("growslice")
@ -2757,7 +2758,7 @@ func appendslice(n *Node, init *Nodes) *Node {
nt.Etype = 1
l = append(l, nod(OAS, s, nt))
if haspointers(l1.Type.Elem()) {
if types.Haspointers(l1.Type.Elem()) {
// copy(s[len(l1):], l2)
nptr1 := nod(OSLICE, s, nil)
nptr1.SetSliceBounds(nod(OLEN, l1, nil), nil, nil)
@ -2767,7 +2768,7 @@ func appendslice(n *Node, init *Nodes) *Node {
fn = substArgTypes(fn, l1.Type, l2.Type)
var ln Nodes
ln.Set(l)
nt := mkcall1(fn, Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
nt := mkcall1(fn, types.Types[TINT], &ln, typename(l1.Type.Elem()), nptr1, nptr2)
l = append(ln.Slice(), nt)
} else if instrumenting && !compiling_runtime {
// rely on runtime to instrument copy.
@ -2785,7 +2786,7 @@ func appendslice(n *Node, init *Nodes) *Node {
fn = substArgTypes(fn, l1.Type, l2.Type)
var ln Nodes
ln.Set(l)
nt := mkcall1(fn, Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
nt := mkcall1(fn, types.Types[TINT], &ln, nptr1, nptr2, nodintconst(s.Type.Elem().Width))
l = append(ln.Slice(), nt)
} else {
// memmove(&s[len(l1)], &l2[0], len(l2)*sizeof(T))
@ -2801,7 +2802,7 @@ func appendslice(n *Node, init *Nodes) *Node {
var ln Nodes
ln.Set(l)
nwid := cheapexpr(conv(nod(OLEN, l2, nil), Types[TUINTPTR]), &ln)
nwid := cheapexpr(conv(nod(OLEN, l2, nil), types.Types[TUINTPTR]), &ln)
nwid = nod(OMUL, nwid, nodintconst(s.Type.Elem().Width))
nt := mkcall1(fn, nil, &ln, nptr1, nptr2, nwid)
@ -2884,7 +2885,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
l = append(l, nx)
nn := temp(Types[TINT])
nn := temp(types.Types[TINT])
l = append(l, nod(OAS, nn, nod(OLEN, ns, nil))) // n = len(s)
nx = nod(OSLICE, ns, nil) // ...s[:n+argc]
@ -2920,7 +2921,7 @@ func walkappend(n *Node, init *Nodes, dst *Node) *Node {
// Also works if b is a string.
//
func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
if haspointers(n.Left.Type.Elem()) {
if types.Haspointers(n.Left.Type.Elem()) {
fn := writebarrierfn("typedslicecopy", n.Left.Type, n.Right.Type)
return mkcall1(fn, n.Type, init, typename(n.Left.Type.Elem()), n.Left, n.Right)
}
@ -2947,7 +2948,7 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
nfrm := nod(OSPTR, nr, nil)
nto := nod(OSPTR, nl, nil)
nlen := temp(Types[TINT])
nlen := temp(types.Types[TINT])
// n = len(to)
l = append(l, nod(OAS, nlen, nod(OLEN, nl, nil)))
@ -2963,8 +2964,8 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
fn := syslook("memmove")
fn = substArgTypes(fn, nl.Type.Elem(), nl.Type.Elem())
nwid := temp(Types[TUINTPTR])
l = append(l, nod(OAS, nwid, conv(nlen, Types[TUINTPTR])))
nwid := temp(types.Types[TUINTPTR])
l = append(l, nod(OAS, nwid, conv(nlen, types.Types[TUINTPTR])))
nwid = nod(OMUL, nwid, nodintconst(nl.Type.Elem().Width))
l = append(l, mkcall1(fn, nil, init, nto, nfrm, nwid))
@ -2974,7 +2975,7 @@ func copyany(n *Node, init *Nodes, runtimecall bool) *Node {
return nlen
}
func eqfor(t *Type, needsize *int) *Node {
func eqfor(t *types.Type, needsize *int) *Node {
// Should only arrive here with large memory or
// a struct/array containing a non-memory field/element.
// Small memory is handled inline, and single non-memory
@ -2990,9 +2991,9 @@ func eqfor(t *Type, needsize *int) *Node {
n := newname(sym)
n.Class = PFUNC
ntype := nod(OTFUNC, nil, nil)
ntype.List.Append(anonfield(typPtr(t)))
ntype.List.Append(anonfield(typPtr(t)))
ntype.Rlist.Append(anonfield(Types[TBOOL]))
ntype.List.Append(anonfield(types.NewPtr(t)))
ntype.List.Append(anonfield(types.NewPtr(t)))
ntype.Rlist.Append(anonfield(types.Types[TBOOL]))
ntype = typecheck(ntype, Etype)
n.Type = ntype.Type
*needsize = 0
@ -3036,7 +3037,7 @@ func walkcompare(n *Node, init *Nodes) *Node {
tab := nod(OITAB, l, nil)
rtyp := typename(r.Type)
if l.Type.IsEmptyInterface() {
tab.Type = typPtr(Types[TUINT8])
tab.Type = types.NewPtr(types.Types[TUINT8])
tab.Typecheck = 1
eqtype = nod(eq, tab, rtyp)
} else {
@ -3093,13 +3094,13 @@ func walkcompare(n *Node, init *Nodes) *Node {
}
// eq algs take pointers
pl := temp(typPtr(t))
pl := temp(types.NewPtr(t))
al := nod(OAS, pl, nod(OADDR, cmpl, nil))
al.Right.Etype = 1 // addr does not escape
al = typecheck(al, Etop)
init.Append(al)
pr := temp(typPtr(t))
pr := temp(types.NewPtr(t))
ar := nod(OAS, pr, nod(OADDR, cmpr, nil))
ar.Right.Etype = 1 // addr does not escape
ar = typecheck(ar, Etop)
@ -3291,7 +3292,7 @@ func walkinrange(n *Node, init *Nodes) *Node {
// This is equivalent to (a-a) ≤ (b-a) && (b-a) < (c-a),
// which is equivalent to 0 ≤ (b-a) && (b-a) < (c-a),
// which is equivalent to uint(b-a) < uint(c-a).
ut := b.Type.toUnsigned()
ut := b.Type.ToUnsigned()
lhs := conv(nod(OSUB, b, a), ut)
rhs := nodintconst(bound)
if negateResult {
@ -3389,7 +3390,7 @@ func usemethod(n *Node) {
}
p0 := t.Params().Field(0)
res0 := t.Results().Field(0)
var res1 *Field
var res1 *types.Field
if t.Results().NumFields() == 2 {
res1 = t.Results().Field(1)
}
@ -3435,7 +3436,7 @@ func usefield(n *Node) {
if t.IsPtr() {
t = t.Elem()
}
field := dotField[typeSym{t.Orig, n.Sym}]
field := dotField[typeSymKey{t.Orig, n.Sym}]
if field == nil {
Fatalf("usefield %v %v without paramfld", n.Left.Type, n.Sym)
}
@ -3456,7 +3457,7 @@ func usefield(n *Node) {
sym := tracksym(outer, field)
if Curfn.Func.FieldTrack == nil {
Curfn.Func.FieldTrack = make(map[*Sym]struct{})
Curfn.Func.FieldTrack = make(map[*types.Sym]struct{})
}
Curfn.Func.FieldTrack[sym] = struct{}{}
}
@ -3629,3 +3630,21 @@ func walkprintfunc(n *Node, init *Nodes) *Node {
a = walkexpr(a, init)
return a
}
// substArgTypes substitutes the given list of types for
// successive occurrences of the "any" placeholder in the
// type syntax expression n.Type.
// The result of substArgTypes MUST be assigned back to old, e.g.
// n.Left = substArgTypes(n.Left, t1, t2)
func substArgTypes(old *Node, types_ ...*types.Type) *Node {
n := *old // make shallow copy
for _, t := range types_ {
dowidth(t)
}
n.Type = types.SubstAny(n.Type, &types_)
if len(types_) > 0 {
Fatalf("substArgTypes: too many argument types")
}
return &n
}