private Instruction SetCacheKeyLocalVariable(Instruction current, MethodDefinition methodDefinition, ILProcessor processor, int cacheKeyIndex, int objectArrayIndex) { if (methodDefinition.IsSetter || methodDefinition.IsGetter) { return(current.AppendStloc(processor, cacheKeyIndex)); } else { // Create object[] for string.format current = current.AppendLdcI4(processor, methodDefinition.Parameters.Count) .Append(processor.Create(OpCodes.Newarr, ModuleDefinition.TypeSystem.Object), processor) .AppendStloc(processor, objectArrayIndex); // Set object[] values for (int i = 0; i < methodDefinition.Parameters.Count; i++) { current = current.AppendLdloc(processor, objectArrayIndex) .AppendLdcI4(processor, i) .AppendLdarg(processor, !methodDefinition.IsStatic ? i + 1 : i) .AppendBoxIfNecessary(processor, methodDefinition.Parameters[i].ParameterType) .Append(processor.Create(OpCodes.Stelem_Ref), processor); } // Call string.format return (current.AppendLdloc(processor, objectArrayIndex) .Append(processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(References.StringFormatMethod)), processor) .AppendStloc(processor, cacheKeyIndex)); } }
private static Instruction SetCacheKeyLocalVariable(BaseModuleWeaver weaver, Instruction current, MethodDefinition methodDefinition, ILProcessor processor, int cacheKeyIndex, int objectArrayIndex) { if (methodDefinition.IsSetter || methodDefinition.IsGetter) { return(current.AppendStloc(processor, cacheKeyIndex)); } else { // Create object[] for string.format int parameterCount = methodDefinition.Parameters.Count + methodDefinition.GenericParameters.Count; current = current .AppendLdcI4(processor, parameterCount) .Append(processor.Create(OpCodes.Newarr, weaver.ModuleDefinition.TypeSystem.Object), processor) .AppendStloc(processor, objectArrayIndex); // Set object[] values for (int i = 0; i < methodDefinition.GenericParameters.Count; i++) { current = current .AppendLdloc(processor, objectArrayIndex) .AppendLdcI4(processor, i) .Append(processor.Create(OpCodes.Ldtoken, methodDefinition.GenericParameters[i]), processor) .Append(processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.SystemTypeGetTypeFromHandleMethod)), processor) .Append(processor.Create(OpCodes.Stelem_Ref), processor); } for (int i = 0; i < methodDefinition.Parameters.Count; i++) { current = current .AppendLdloc(processor, objectArrayIndex) .AppendLdcI4(processor, methodDefinition.GenericParameters.Count + i) .AppendLdarg(processor, !methodDefinition.IsStatic ? i + 1 : i) .AppendBoxIfNecessary(processor, methodDefinition.Parameters[i].ParameterType) .Append(processor.Create(OpCodes.Stelem_Ref), processor); } // Call string.format var ins = processor.Create(OpCodes.Call, methodDefinition.Module.ImportMethod(ReferenceFinder.StringFormatMethod)); return(current .AppendLdloc(processor, objectArrayIndex) .Append(ins, processor) .AppendStloc(processor, cacheKeyIndex)); } }
private void WeavePropertySetter(MethodDefinition setter, MethodReference propertyGet) { setter.Body.InitLocals = true; setter.Body.SimplifyMacros(); if (propertyGet.DeclaringType.HasGenericParameters) { propertyGet = propertyGet.MakeHostInstanceGeneric(propertyGet.DeclaringType.GenericParameters.Cast <TypeReference>().ToArray()); } Instruction firstInstruction = setter.Body.Instructions.First(); ILProcessor processor = setter.Body.GetILProcessor(); // Add local variables int cacheKeyIndex = setter.AddVariable(ModuleDefinition.TypeSystem.String); // Generate CacheKeyTemplate string cacheKey = CreateCacheKeyString(setter); Instruction current = firstInstruction.Prepend(processor.Create(OpCodes.Ldstr, cacheKey), processor); // Create set cache key current = current.AppendStloc(processor, cacheKeyIndex); current = InjectCacheKeyCreatedCode(setter, current, processor, cacheKeyIndex); if (LogDebugOutput) { current = AppendDebugWrite(current, processor, "Clearing cache."); } if (!propertyGet.Resolve().IsStatic) { current = current.AppendLdarg(processor, 0); } current .Append(processor.Create(OpCodes.Call, setter.Module.Import(propertyGet)), processor) .AppendLdloc(processor, cacheKeyIndex) .Append(processor.Create(OpCodes.Callvirt, setter.Module.Import( CacheTypeGetRemoveMethod(propertyGet.ReturnType.Resolve(), CacheTypeRemoveMethodName))), processor); setter.Body.OptimizeMacros(); }
private void WeavePropertySetter(MethodDefinition setter, MethodDefinition propertyGet) { setter.Body.InitLocals = true; setter.Body.SimplifyMacros(); Instruction firstInstruction = setter.Body.Instructions.First(); ILProcessor processor = setter.Body.GetILProcessor(); // Add local variables int cacheKeyIndex = setter.AddVariable <string>(); // Generate CacheKeyTemplate string cacheKey = CreateCacheKeyString(setter); Instruction current = firstInstruction.Prepend(processor.Create(OpCodes.Ldstr, cacheKey), processor); // Create set cache key current = current.AppendStloc(processor, cacheKeyIndex); current = InjectCacheKeyCreatedCode(setter, current, processor, cacheKeyIndex); if (LogDebugOutput) { current = current.AppendDebugWrite(processor, "Clearing cache.", ModuleDefinition); } if (!setter.IsStatic) { current = current.AppendLdarg(processor, 0); } current.Append(processor.Create(OpCodes.Call, setter.Module.Import(propertyGet)), processor) .AppendLdloc(processor, cacheKeyIndex) .Append( processor.Create(OpCodes.Callvirt, setter.Module.Import(CacheTypeGetRemoveMethod(propertyGet.ReturnType.Resolve(), CacheTypeRemoveMethodName))), processor); setter.Body.OptimizeMacros(); }