예제 #1
0
        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);
     }
 }