protected internal override void VisitLdFlda(LdFlda inst) { base.VisitLdFlda(inst); // Get display class info if (!IsDisplayClassFieldAccess(inst, out _, out DisplayClass displayClass, out IField field)) { return; } // We want the specialized version, so that display-class type parameters are // substituted with the type parameters from the use-site. var fieldType = field.Type; // However, use the unspecialized member definition to make reference comparisons in dictionary possible. field = (IField)field.MemberDefinition; if (!displayClass.Variables.TryGetValue(field, out var v)) { context.Step($"Introduce captured variable for {field.FullName}", inst); // Introduce a fresh variable for the display class field. Debug.Assert(displayClass.Definition == field.DeclaringTypeDefinition); v = displayClass.DeclaringFunction.RegisterVariable(VariableKind.Local, fieldType, field.Name); v.HasInitialValue = true; v.CaptureScope = displayClass.CaptureScope; inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); displayClass.Variables.Add(field, v); } else { context.Step($"Reuse captured variable {v.Name} for {field.FullName}", inst); inst.ReplaceWith(new LdLoca(v).WithILRange(inst)); } }
protected internal override void VisitLdFlda(LdFlda inst) { base.VisitLdFlda(inst); // Get display class info if (!IsDisplayClassFieldAccess(inst, out _, out DisplayClass displayClass, out IField field)) return; var keyField = (IField)field.MemberDefinition; var v = displayClass.VariablesToDeclare[keyField]; context.Step($"Replace {field.Name} with captured variable {v.Name}", inst); ILVariable variable = v.GetOrDeclare(); inst.ReplaceWith(new LdLoca(variable).WithILRange(inst)); // add captured variable to all descendant functions from the declaring function to this use-site function foreach (var f in currentFunctions) { if (f == variable.Function) break; f.CapturedVariables.Add(variable); } }