// ordinary ones in the symbol table; see oldname.
// unhook them.
// make the list of pointers for the closure call.
- var v *Node
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- v = l.N
+ for _, v := range func_.Func.Cvars() {
v.Name.Param.Closure.Name.Param.Closure = v.Name.Param.Outer
v.Name.Param.Outerexpr = oldname(v.Sym)
}
}
func typecheckclosure(func_ *Node, top int) {
- var n *Node
-
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- n = l.N.Name.Param.Closure
+ for _, ln := range func_.Func.Cvars() {
+ n := ln.Name.Param.Closure
if !n.Name.Captured {
n.Name.Captured = true
if n.Name.Decldepth == 0 {
// We use value capturing for values <= 128 bytes that are never reassigned
// after capturing (effectively constant).
func capturevars(xfunc *Node) {
- var v *Node
var outer *Node
lno := int(lineno)
func_ := xfunc.Func.Closure
func_.Func.Enter = nil
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- v = l.N
+ for _, v := range func_.Func.Cvars() {
if v.Type == nil {
// if v->type is nil, it means v looked like it was
// going to be used in the closure but wasn't.
original_dcl := xfunc.Func.Dcl
xfunc.Func.Dcl = nil
- var v *Node
var addr *Node
var fld *Type
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- v = l.N
+ for _, v := range func_.Func.Cvars() {
if v.Op == OXXX {
continue
}
var body *NodeList
offset := int64(Widthptr)
var addr *Node
- var v *Node
var cv *Node
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- v = l.N
+ for _, v := range func_.Func.Cvars() {
if v.Op == OXXX {
continue
}
func walkclosure(func_ *Node, init **NodeList) *Node {
// If no closure vars, don't bother wrapping.
- if func_.Func.Cvars == nil {
+ if len(func_.Func.Cvars()) == 0 {
return func_.Func.Closure.Func.Nname
}
typ.List = list1(Nod(ODCLFIELD, newname(Lookup(".F")), typenod(Types[TUINTPTR])))
var typ1 *Node
- var v *Node
- for l := func_.Func.Cvars; l != nil; l = l.Next {
- v = l.N
+ for _, v := range func_.Func.Cvars() {
if v.Op == OXXX {
continue
}
Shortname *Node
Enter *NodeList
Exit *NodeList
- Cvars *NodeList // closure params
- Dcl []*Node // autodcl for this func/closure
- Inldcl []*Node // copy of dcl for use in inlining
+ cvars *[]*Node // closure params
+ Dcl []*Node // autodcl for this func/closure
+ Inldcl []*Node // copy of dcl for use in inlining
Closgen int
Outerfunc *Node
Fieldtrack []*Type
Needctxt bool // function uses context register (has closure variables)
}
+// Cvars returns the closure variables for this Func.
+// These are referenced variables that are defined in enclosing
+// functions.
+// The cvars field is a pointer to save space, since most Func values
+// have no cvars.
+func (f *Func) Cvars() []*Node {
+ if f.cvars == nil {
+ return nil
+ }
+ return *f.cvars
+}
+
+// AppendCvar appends a new closure variable.
+func (f *Func) CvarAppend(n *Node) {
+ if f.cvars == nil {
+ f.cvars = &[]*Node{n}
+ } else {
+ *f.cvars = append(*f.cvars, n)
+ }
+}
+
type Op uint8
// Node ops.