for l := func_.Cvars; l != nil; l = l.Next {
n = l.N.Closure
- if n.Captured == 0 {
- n.Captured = 1
+ if !n.Captured {
+ n.Captured = true
if n.Decldepth == 0 {
Fatal("typecheckclosure: var %v does not have decldepth assigned", Nconv(n, obj.FmtShort))
}
// Ignore assignments to the variable in straightline code
// preceding the first capturing by a closure.
if n.Decldepth == decldepth {
- n.Assigned = 0
+ n.Assigned = false
}
}
}
v.Outerexpr = nil
// out parameters will be assigned to implicitly upon return.
- if outer.Class != PPARAMOUT && !v.Closure.Addrtaken && v.Closure.Assigned == 0 && v.Type.Width <= 128 {
- v.Byval = 1
+ if outer.Class != PPARAMOUT && !v.Closure.Addrtaken && !v.Closure.Assigned && v.Type.Width <= 128 {
+ v.Byval = true
} else {
v.Closure.Addrtaken = true
outer = Nod(OADDR, outer, nil)
name = v.Curfn.Nname.Sym
}
how := "ref"
- if v.Byval != 0 {
+ if v.Byval {
how = "value"
}
- Warnl(int(v.Lineno), "%v capturing by %s: %v (addr=%d assign=%d width=%d)", Sconv(name, 0), how, Sconv(v.Sym, 0), v.Closure.Addrtaken, v.Closure.Assigned, int32(v.Type.Width))
+ Warnl(int(v.Lineno), "%v capturing by %s: %v (addr=%v assign=%v width=%d)", Sconv(name, 0), how, Sconv(v.Sym, 0), v.Closure.Addrtaken, v.Closure.Assigned, int32(v.Type.Width))
}
typecheck(&outer, Erv)
}
fld = typ(TFIELD)
fld.Funarg = 1
- if v.Byval != 0 {
+ if v.Byval {
// If v is captured by value, we merely downgrade it to PPARAM.
v.Class = PPARAM
cv = Nod(OCLOSUREVAR, nil, nil)
cv.Type = v.Type
- if v.Byval == 0 {
+ if !v.Byval {
cv.Type = Ptrto(v.Type)
}
offset = Rnd(offset, int64(cv.Type.Align))
cv.Xoffset = offset
offset += cv.Type.Width
- if v.Byval != 0 && v.Type.Width <= int64(2*Widthptr) && Thearch.Thechar == '6' {
+ if v.Byval && v.Type.Width <= int64(2*Widthptr) && Thearch.Thechar == '6' {
// If it is a small variable captured by value, downgrade it to PAUTO.
// This optimization is currently enabled only for amd64, see:
// https://github.com/golang/go/issues/9865
addr.Curfn = xfunc
xfunc.Dcl = list(xfunc.Dcl, addr)
v.Heapaddr = addr
- if v.Byval != 0 {
+ if v.Byval {
cv = Nod(OADDR, cv, nil)
}
body = list(body, Nod(OAS, addr, cv))
continue
}
typ1 = typenod(v.Type)
- if v.Byval == 0 {
+ if !v.Byval {
typ1 = Nod(OIND, typ1, nil)
}
typ.List = list(typ.List, Nod(ODCLFIELD, newname(v.Sym), typ1))
xtype.Rlist = l
- xfunc.Dupok = 1
+ xfunc.Dupok = true
xfunc.Nname = newname(sym)
xfunc.Nname.Sym.Flags |= SymExported // disable export
xfunc.Nname.Ntype = xtype
continue
}
a = v.Closure
- if v.Byval == 0 {
+ if !v.Byval {
a = Nod(OADDR, a, nil)
a.Lineno = v.Lineno
a.Escloopdepth = e.loopdepth
fp += " addrtaken"
}
- if n.Assigned != 0 {
+ if n.Assigned {
fp += " assigned"
}
nam = nil
}
ptxt = Thearch.Gins(obj.ATEXT, nam, &nod1)
- if fn.Dupok != 0 {
+ if fn.Dupok {
ptxt.From3.Offset |= obj.DUPOK
}
- if fn.Wrapper != 0 {
+ if fn.Wrapper {
ptxt.From3.Offset |= obj.WRAPPER
}
if fn.Needctxt {
for j = nfree; j < len(var_); j++ {
v1 = inuse[j]
if debugmerge > 0 && Debug['v'] != 0 {
- fmt.Printf("consider %v: maybe %v: type=%v,%v addrtaken=%d,%d\n", Nconv(v.node, obj.FmtSharp), Nconv(v1.node, obj.FmtSharp), Tconv(t, 0), Tconv(v1.node.Type, 0), v.node.Addrtaken, v1.node.Addrtaken)
+ fmt.Printf("consider %v: maybe %v: type=%v,%v addrtaken=%v,%v\n", Nconv(v.node, obj.FmtSharp), Nconv(v1.node, obj.FmtSharp), Tconv(t, 0), Tconv(v1.node.Type, 0), v.node.Addrtaken, v1.node.Addrtaken)
}
// Require the types to match but also require the addrtaken bits to match.
n.Left = newname(methodsym(method.Sym, methodrcvr, 0))
fn.Nbody = list(fn.Nbody, n)
} else {
- fn.Wrapper = 1 // ignore frame for panic+recover matching
+ fn.Wrapper = true // ignore frame for panic+recover matching
call := Nod(OCALL, dot, nil)
call.List = args
call.Isddd = uint8(isddd)
// wrappers where T is anonymous (struct or interface) can be duplicated.
if rcvr.Etype == TSTRUCT || rcvr.Etype == TINTER || Isptr[rcvr.Etype] && rcvr.Type.Etype == TSTRUCT {
- fn.Dupok = 1
+ fn.Dupok = true
}
typecheck(&fn, Etop)
typechecklist(fn.Nbody, Etop)
funcbody(fn)
Curfn = fn
- fn.Dupok = 1
+ fn.Dupok = true
typecheck(&fn, Etop)
typechecklist(fn.Nbody, Etop)
Curfn = nil
funcbody(fn)
Curfn = fn
- fn.Dupok = 1
+ fn.Dupok = true
typecheck(&fn, Etop)
typechecklist(fn.Nbody, Etop)
Curfn = nil
Isddd uint8
Readonly bool
Implicit uint8
- Addrtaken bool // address taken, even if not moved to heap
- Assigned uint8 // is the variable ever assigned to
- Captured uint8 // is the variable captured by a closure
- Byval uint8 // is the variable captured by value or by reference
- Dupok uint8 // duplicate definitions ok (for func)
- Wrapper uint8 // is method wrapper (for func)
- Reslice uint8 // this is a reslice x = x[0:y] or x = append(x, ...)
- Likely int8 // likeliness of if statement
- Hasbreak bool // has break statement
- Needzero bool // if it contains pointers, needs to be zeroed on function entry
- Needctxt bool // function uses context register (has closure variables)
- Esc uint // EscXXX
+ Addrtaken bool // address taken, even if not moved to heap
+ Assigned bool // is the variable ever assigned to
+ Captured bool // is the variable captured by a closure
+ Byval bool // is the variable captured by value or by reference
+ Dupok bool // duplicate definitions ok (for func)
+ Wrapper bool // is method wrapper (for func)
+ Reslice bool // this is a reslice x = x[0:y] or x = append(x, ...)
+ Likely int8 // likeliness of if statement
+ Hasbreak bool // has break statement
+ Needzero bool // if it contains pointers, needs to be zeroed on function entry
+ Needctxt bool // function uses context register (has closure variables)
+ Esc uint // EscXXX
Funcdepth int
// most nodes
r := outervalue(n)
var l *Node
for l = n; l != r; l = l.Left {
- l.Assigned = 1
+ l.Assigned = true
if l.Closure != nil {
- l.Closure.Assigned = 1
+ l.Closure.Assigned = true
}
}
- l.Assigned = 1
+ l.Assigned = true
if l.Closure != nil {
- l.Closure.Assigned = 1
+ l.Closure.Assigned = true
}
}
OSLICE3,
OSLICESTR:
if false && samesafeexpr(n.Left, n.Right.Left) && (n.Right.Right.Left == nil || iszero(n.Right.Right.Left)) {
- n.Right.Reslice = 1
+ n.Right.Reslice = true
}
// For x = append(x, ...), x can be updated in place when there is capacity,
// TODO(rsc): Reenable once the emitted code does update the pointer.
case OAPPEND:
if false && n.Right.List != nil && samesafeexpr(n.Left, n.Right.List.N) {
- n.Right.Reslice = 1
+ n.Right.Reslice = true
}
}
}
return a == b
}
-func paramoutheap(fn *Node) int {
+func paramoutheap(fn *Node) bool {
for l := fn.Dcl; l != nil; l = l.Next {
switch l.N.Class {
case PPARAMOUT,
PPARAMOUT | PHEAP:
- return bool2int(l.N.Addrtaken)
+ return l.N.Addrtaken
// stop early - parameters are over
case PAUTO,
PAUTO | PHEAP:
- return 0
+ return false
}
}
- return 0
+ return false
}
// adds "adjust" to all the argument locations for the call n.
if n.List == nil {
break
}
- if (Curfn.Type.Outnamed != 0 && count(n.List) > 1) || paramoutheap(Curfn) != 0 {
+ if (Curfn.Type.Outnamed != 0 && count(n.List) > 1) || paramoutheap(Curfn) {
// assign to the function out parameters,
// so that reorder3 can fix up conflicts
var rl *NodeList
// generate the write barrier directly in that case.
// (It does not yet, but the cost of the write barrier will be
// small compared to the cost of the allocation.)
- if r.Reslice != 0 {
+ if r.Reslice {
switch r.Op {
case OSLICE,
OSLICE3,