// and has one float64 argument and no results,
// the generated code looks like:
//
- // clos = &struct{.F uintptr; i *int; s *string}{func.1, &i, &s}
+ // clos = &struct{F uintptr; X0 *int; X1 *string}{func.1, &i, &s}
//
// The use of the struct provides type information to the garbage
- // collector so that it can walk the closure. We could use (in this case)
- // [3]unsafe.Pointer instead, but that would leave the gc in the dark.
- // The information appears in the binary in the form of type descriptors;
- // the struct is unnamed so that closures in multiple packages with the
- // same struct type can share the descriptor.
-
- // Make sure the .F field is in the same package as the rest of the
- // fields. This deals with closures in instantiated functions, which are
- // compiled as if from the source package of the generic function.
- var pkg *types.Pkg
- if len(clo.Func.ClosureVars) == 0 {
- pkg = types.LocalPkg
- } else {
- for _, v := range clo.Func.ClosureVars {
- if pkg == nil {
- pkg = v.Sym().Pkg
- } else if pkg != v.Sym().Pkg {
- base.Fatalf("Closure variables from multiple packages: %+v", clo)
- }
- }
- }
-
- fields := []*types.Field{
- types.NewField(base.Pos, pkg.Lookup(".F"), types.Types[types.TUINTPTR]),
- }
- for _, v := range clo.Func.ClosureVars {
+ // collector so that it can walk the closure. We could use (in this
+ // case) [3]unsafe.Pointer instead, but that would leave the gc in
+ // the dark. The information appears in the binary in the form of
+ // type descriptors; the struct is unnamed and uses exported field
+ // names so that closures in multiple packages with the same struct
+ // type can share the descriptor.
+
+ fields := make([]*types.Field, 1+len(clo.Func.ClosureVars))
+ fields[0] = types.NewField(base.AutogeneratedPos, types.LocalPkg.Lookup("F"), types.Types[types.TUINTPTR])
+ for i, v := range clo.Func.ClosureVars {
typ := v.Type()
if !v.Byval() {
typ = types.NewPtr(typ)
}
- fields = append(fields, types.NewField(base.Pos, v.Sym(), typ))
+ fields[1+i] = types.NewField(base.AutogeneratedPos, types.LocalPkg.LookupNum("X", i), typ)
}
typ := types.NewStruct(fields)
typ.SetNoalg(true)