/// <summary> /// If a definition should be captured, capture it. Otherwise noop. /// /// The act of capturing means mapping the definition (or its type's interned id if the definition is a reference to THIS) to /// a new BoundField object that represents a field in the closure class. /// </summary> /// <param name="definition"></param> private void CaptureDefinition(object definition) { IThisReference/*?*/ thisRef = definition as IThisReference; if (thisRef != null) { definition = thisRef.Type.ResolvedType.InternedKey; } if (this.fieldForCapturedLocalOrParameter.ContainsKey(definition)) return; IName/*?*/ name = null; ITypeReference/*?*/ type = null; ILocalDefinition/*?*/ local = definition as ILocalDefinition; var containingClass = this.generatedclosureClass; if (local != null) { if (!this.localOrParameter2ClosureClass.TryGetValue(local, out containingClass)) return; if (false && containingClass == this.generatedclosureClass) { // A use of a local is captured only if it is found in a *nested* closure, // not the closure where the local is defined. return; } name = local.Name; type = local.Type; } else { IParameterDefinition/*?*/ par = definition as IParameterDefinition; if (par != null) { if (!this.localOrParameter2ClosureClass.TryGetValue(par, out containingClass)) return; name = par.Name; type = par.Type; } else { if (definition is uint) { type = thisRef.Type; name = this.nameTable.GetNameFor("__this value"); } else return; } } if (name == null) return; FieldDefinition field = new FieldDefinition() { ContainingTypeDefinition = containingClass, InternFactory = this.host.InternFactory, Name = name, Type = this.copyTypeToClosure.Visit(type), Visibility = TypeMemberVisibility.Public }; containingClass.Fields.Add(field); BoundField be = new BoundField(field, field.Type); this.fieldForCapturedLocalOrParameter.Add(definition, be); }
/// <summary> /// Create fields for the closure class, which include fields for captured variables and fields for maintaining the state machine. /// </summary> private void CreateIteratorClosureFields(IteratorClosureInformation iteratorClosure) //^ requires (iteratorClosure.ElementType != null); { // Create fields of the closure class: parameters and this if (!this.method.IsStatic) { FieldDefinition field = new FieldDefinition(); // TODO: naming convention should use csc's. field.InternFactory = this.host.InternFactory; field.Name = this.host.NameTable.GetNameFor("<>__" + "this"); //ITypeReference typeRef; //if (TypeHelper.TryGetFullyInstantiatedSpecializedTypeReference(method.ContainingTypeDefinition, out typeRef)) // field.Type = typeRef; //else // field.Type = method.ContainingTypeDefinition; field.Type = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory); field.Visibility = TypeMemberVisibility.Public; field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; iteratorClosure.ThisField = field; BoundField boundField = new BoundField(field, iteratorClosure.ThisFieldReference.Type); this.FieldForCapturedLocalOrParameter.Add(new ThisReference(), boundField); } foreach (IParameterDefinition parameter in this.method.Parameters) { FieldDefinition field = new FieldDefinition(); field.InternFactory = this.host.InternFactory; field.Name = parameter.Name; field.Type = this.copyTypeToClosure.Visit(parameter.Type); field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; field.Visibility = TypeMemberVisibility.Public; iteratorClosure.AddField(field); BoundField boundField = new BoundField(field, field.Type); this.FieldForCapturedLocalOrParameter.Add(parameter, boundField); } // Create fields of the closure class: Locals foreach (ILocalDefinition local in this.allLocals) { FieldDefinition field = new FieldDefinition(); field.InternFactory = this.host.InternFactory; field.Name = this.host.NameTable.GetNameFor("<>__" + local.Name.Value + this.privateHelperTypes.Count); field.Type = this.copyTypeToClosure.Visit(local.Type); field.Visibility = TypeMemberVisibility.Public; field.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; iteratorClosure.AddField(field); BoundField boundField = new BoundField(field, field.Type); this.FieldForCapturedLocalOrParameter.Add(local, boundField); } // Create fields: current, state, and l_initialThreadId FieldDefinition current = new FieldDefinition(); current.InternFactory = this.host.InternFactory; current.Name = this.host.NameTable.GetNameFor("<>__" + "current"); current.Type = iteratorClosure.ElementType; current.Visibility = TypeMemberVisibility.Private; current.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; iteratorClosure.CurrentField = current; FieldDefinition state = new FieldDefinition(); state.InternFactory = this.host.InternFactory; state.Name = this.host.NameTable.GetNameFor("<>__" + "state"); state.Type = this.host.PlatformType.SystemInt32; state.Visibility = TypeMemberVisibility.Private; state.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; iteratorClosure.StateField = state; FieldDefinition initialThreadId = new FieldDefinition(); initialThreadId.InternFactory = this.host.InternFactory; initialThreadId.Name = this.host.NameTable.GetNameFor("<>__" + "l_initialThreadId"); initialThreadId.Type = this.host.PlatformType.SystemInt32; initialThreadId.Visibility = TypeMemberVisibility.Private; initialThreadId.ContainingTypeDefinition = iteratorClosure.ClosureDefinition; iteratorClosure.InitialThreadId = initialThreadId; }