public NodeObject(int dimension, int validPathCount, NamespaceTypeDefinition thisClass, MethodDefinition constructorToUse, PathElement pathElement, List<int> positionInGraph, int validPathId) : this(dimension, validPathCount, thisClass, constructorToUse, pathElement, positionInGraph) { // add the id of the valid path to the list this.elementOfValidPath.Add(validPathId); }
internal MethodBody(MethodDefinition methodDefinition, bool isLocalsInited, ushort stackSize, uint bodySize) { this.MethodDefinition = methodDefinition; this.IsLocalsInited = isLocalsInited; this.LocalVariables = null; this.StackSize = stackSize; this.bodySize = bodySize; }
static void AssertCode (string expected, MethodDefinition method) { Assert.IsTrue (method.HasBody); Assert.IsNotNull (method.Body); Assert.AreEqual (Normalize (expected), Normalize (Formatter.FormatMethodBody (method))); }
void InjectAsStreamReader(TypeDefinition targetType, FieldDefinition fieldDefinition) { AsStreamReaderMethod = new MethodDefinition("AsStreamReader", staticMethodAttributes, StreamReaderTypeReference); var streamVariable = new VariableDefinition(StreamTypeReference); AsStreamReaderMethod.Body.Variables.Add(streamVariable); var pathParam = new ParameterDefinition(ModuleDefinition.TypeSystem.String); AsStreamReaderMethod.Parameters.Add(pathParam); AsStreamReaderMethod.Body.InitLocals = true; var inst = AsStreamReaderMethod.Body.Instructions; var skipReturn = Instruction.Create(OpCodes.Nop); inst.Add(Instruction.Create(OpCodes.Ldsfld, fieldDefinition)); inst.Add(Instruction.Create(OpCodes.Ldarg, pathParam)); inst.Add(Instruction.Create(OpCodes.Callvirt, GetManifestResourceStreamMethod)); inst.Add(Instruction.Create(OpCodes.Stloc, streamVariable)); inst.Add(Instruction.Create(OpCodes.Ldloc, streamVariable)); inst.Add(Instruction.Create(OpCodes.Brtrue_S, skipReturn)); inst.Add(Instruction.Create(OpCodes.Ldnull)); inst.Add(Instruction.Create(OpCodes.Ret)); inst.Add(skipReturn); inst.Add(Instruction.Create(OpCodes.Ldloc, streamVariable)); inst.Add(Instruction.Create(OpCodes.Newobj, StreamReaderConstructorReference)); inst.Add(Instruction.Create(OpCodes.Ret)); targetType.Methods.Add(AsStreamReaderMethod); }
public void Process(MethodDefinition method) { method.Body.SimplifyMacros(); var instructions = method.Body.Instructions; for (var index = 0; index < instructions.Count; index++) { var line = instructions[index]; if (line.OpCode != OpCodes.Call) { continue; } var methodReference = line.Operand as MethodReference; if (methodReference == null) { continue; } if (IsSetExceptionMethod(methodReference)) { var previous = instructions[index-1]; instructions.Insert(index, Instruction.Create(OpCodes.Call, HandleMethodFinder.HandleMethod)); index++; instructions.Insert(index, Instruction.Create(previous.OpCode, (VariableDefinition)previous.Operand)); index++; } } method.Body.OptimizeMacros(); }
public MethodDebugInformation Read(MethodDefinition method) { var method_token = method.MetadataToken; PdbFunction function; if (!functions.TryGetValue (method_token.ToUInt32 (), out function)) return null; var symbol = new MethodDebugInformation (method); ReadSequencePoints (function, symbol); if (!function.scopes.IsNullOrEmpty()) symbol.scope = ReadScopeAndLocals (function.scopes [0], symbol); if (function.scopes.Length > 1) { for (int i = 1; i < function.scopes.Length; i++) { var s = ReadScopeAndLocals (function.scopes [i], symbol); if (!AddScope (symbol.scope.Scopes, s)) symbol.scope.Scopes.Add (s); } } return symbol; }
bool FindIsChangedEventInvokerMethodDefinition(TypeDefinition type, out MethodDefinition methodDefinition) { //todo: check bool type methodDefinition = null; var propertyDefinition = type.Properties .FirstOrDefault(x => x.Name == isChangedPropertyName && x.SetMethod != null && x.SetMethod.IsPublic ); if (propertyDefinition != null) { if (propertyDefinition.PropertyType.FullName != ModuleDefinition.TypeSystem.Boolean.FullName) { LogWarning(string.Format("Found '{0}' but is was of type '{1}' instead of '{2}' so it will not be used.", propertyDefinition.GetName(), propertyDefinition.PropertyType.Name, ModuleDefinition.TypeSystem.Boolean.Name)); return false; } if (propertyDefinition.SetMethod.IsStatic) { throw new WeavingException(string.Format("Found '{0}' but is was static. Change it to non static.", propertyDefinition.GetName())); } methodDefinition = propertyDefinition.SetMethod; } return methodDefinition != null; }
public static bool IsBeforeAfterOnChangedMethod(MethodDefinition method) { var parameters = method.Parameters; return parameters.Count == 2 && parameters[0].ParameterType.FullName == "System.Object" && parameters[1].ParameterType.FullName == "System.Object"; }
public CodeReader (MethodDefinition method, MetadataReader reader) : base (reader.image.Stream) { this.reader = reader; this.reader.context = method; this.Position = (int) reader.image.ResolveVirtualAddress ((uint) method.RVA); }
public void Execute(MethodDefinition getMethod) { processedMethods.Add(getMethod); if (getMethod.Body == null) { return; } foreach (var instruction in getMethod.Body.Instructions) { Instructions.Add(instruction); if (!IsCall(instruction.OpCode)) { continue; } var methodDefinition = instruction.Operand as MethodDefinition; if (methodDefinition == null) { continue; } if (methodDefinition.IsGetter || methodDefinition.IsSetter) { continue; } if (processedMethods.Contains(methodDefinition)) { continue; } if (methodDefinition.DeclaringType != typeDefinition) { continue; } Execute(methodDefinition); } }
private static MethodReference CloneMethodWithDeclaringType(MethodDefinition methodDef, TypeReference declaringTypeRef) { if (!declaringTypeRef.IsGenericInstance || methodDef == null) { return methodDef; } var methodRef = new MethodReference(methodDef.Name, methodDef.ReturnType, declaringTypeRef) { CallingConvention = methodDef.CallingConvention, HasThis = methodDef.HasThis, ExplicitThis = methodDef.ExplicitThis }; foreach (var paramDef in methodDef.Parameters) { methodRef.Parameters.Add(new ParameterDefinition(paramDef.Name, paramDef.Attributes, paramDef.ParameterType)); } foreach (var genParamDef in methodDef.GenericParameters) { methodRef.GenericParameters.Add(new GenericParameter(genParamDef.Name, methodRef)); } return methodRef; }
public static MethodDefinition GetMoreVisibleMethod(this MethodDefinition method, MethodDefinition other) { if (method == null) return other; if (other == null) return method; if (method.IsPrivate) { return other; } if (method.IsFamily || method.IsAssembly) { if (other.IsPublic || other.IsFamilyOrAssembly) { return other; } return method; } if (method.IsFamilyOrAssembly) { if (other.IsPublic) { return other; } return method; } return method; }
public static void Parse (MethodDefinition method, IILVisitor visitor) { if (method == null) throw new ArgumentNullException ("method"); if (visitor == null) throw new ArgumentNullException ("visitor"); if (!method.HasBody || !method.HasImage) throw new ArgumentException (); var context = CreateContext (method, visitor); var code = context.Code; code.MoveTo (method.RVA); var flags = code.ReadByte (); switch (flags & 0x3) { case 0x2: // tiny int code_size = flags >> 2; ParseCode (code_size, context); break; case 0x3: // fat code.position--; ParseFatMethod (context); break; default: throw new NotSupportedException (); } }
static MethodDefinition GetActualMethod(MethodDefinition method) { var isTypeCompilerGenerated = method.DeclaringType.IsCompilerGenerated(); if (isTypeCompilerGenerated) { var rootType = method.DeclaringType.DeclaringType; if (rootType != null) { foreach (var parentClassMethod in rootType.Methods) { if (method.DeclaringType.Name.StartsWith("<" + parentClassMethod.Name + ">")) { return parentClassMethod; } if (method.Name.StartsWith("<" + parentClassMethod.Name + ">")) { return parentClassMethod; } } } } var isMethodCompilerGenerated = method.IsCompilerGenerated(); if (isMethodCompilerGenerated) { foreach (var parentClassMethod in method.DeclaringType.Methods) { if (method.Name.StartsWith("<" + parentClassMethod.Name + ">")) { return parentClassMethod; } } } return method; }
public static bool IsSenderPropertyChangedArgMethod(MethodDefinition method) { var parameters = method.Parameters; return parameters.Count == 2 && parameters[0].ParameterType.FullName == "System.Object" && parameters[1].ParameterType.FullName == "System.ComponentModel.PropertyChangedEventArgs"; }
void Replace(MethodDefinition methodDefinition) { if (methodDefinition == null) { return; } if (methodDefinition.IsAbstract) { return; } //for delegates if (methodDefinition.Body == null) { return; } foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.OpCode != OpCodes.Call) { continue; } foreach (var method in MethodCache) { if (instruction.Operand == method) { instruction.OpCode = OpCodes.Callvirt; } } } }
public void ImportAssemblyLoader() { var existingILTemplate = Module.GetAllTypeDefinitions().FirstOrDefault(x => x.FullName == "Costura.AssemblyLoader"); if (existingILTemplate != null) { AttachMethod = existingILTemplate.Methods.First(x => x.Name == "Attach"); return; } var moduleDefinition = GetTemplateModuleDefinition(); if (!CreateTemporaryAssemblies) { sourceType = moduleDefinition.Types.First(x => x.Name == "ILTemplate"); } else { sourceType = moduleDefinition.Types.First(x => x.Name == "ILTemplateWithTempAssembly"); } targetType = new TypeDefinition("Costura", "AssemblyLoader", sourceType.Attributes, Resolve(sourceType.BaseType)); Module.Types.Add(targetType); CopyFields(sourceType); CopyMethod(sourceType.Methods.First(x => x.Name == "ResolveAssembly")); AttachMethod = CopyMethod(sourceType.Methods.First(x => x.Name == "Attach")); }
/// <summary> /// Default ctor /// </summary> internal CodeReader(MethodDefinition method, CodeAttribute codeAttribute, byte[] code, ConstantPool cp) { this.method = method; this.codeAttribute = codeAttribute; this.code = code; this.cp = cp; }
void ProcessMethod(MethodDefinition method) { if (method.IsYield()) { if (method.ContainsTimeAttribute()) { LogError("Could not process '" + method.FullName + "' since methods that yield are currently not supported. Please remove the [Time] attribute from that method."); return; } LogInfo("Skipping '" + method.FullName + "' since methods that yield are not supported."); return; } if (method.IsAsync()) { var asyncProcessor = new AsyncMethodProcessor { ModuleWeaver = this, Method = method, }; asyncProcessor.Process(); return; } var methodProcessor = new MethodProcessor { ModuleWeaver = this, Method = method, }; methodProcessor.Process(); }
/// <summary> /// Creates the default constructor. /// </summary> public MethodDefinition CreateDefaultConstructor(TypeDefinition type) { _logInfo("AddDefaultConstructor() " + type.Name); // Create method for a constructor var methodAttributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; var method = new MethodDefinition(".ctor", methodAttributes, _moduleDefinition.TypeSystem.Void); // Set parameters for constructor, and add corresponding assignment in method body: // 1. Add each property in the class as a parameter for the constructor // 2. Set the properties in the class from the constructor parameters // Properties marked with the [ImmutableClassIgnore] attribute are ignored foreach (var prop in type.Properties) { if (prop.CustomAttributes.ContainsAttribute("ImmutableClassIgnoreAttribute")) { _logInfo("Ignoring property " + prop.Name); continue; } string paramName = Char.ToLowerInvariant(prop.Name [0]) + prop.Name.Substring (1); // convert first letter of name to lowercase _logInfo("Adding parameter " + paramName + " to ctor"); var pd = (new ParameterDefinition(paramName, ParameterAttributes.HasDefault, prop.PropertyType)); method.Parameters.Add(pd); _logInfo("Setting property " + prop.Name); method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg_0)); method.Body.Instructions.Add(Instruction.Create(OpCodes.Ldarg, pd)); method.Body.Instructions.Add(Instruction.Create(OpCodes.Call, prop.SetMethod)); } method.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); return method; }
public PInvokeInfo (MethodDefinition meth, PInvokeAttributes attrs, string entryPoint, ModuleReference mod) : this (meth) { m_attributes = attrs; m_entryPoint = entryPoint; m_module = mod; }
void CreateDisposeBoolMethod() { DisposeBoolMethod = new MethodDefinition("Dispose", MethodAttributes.HideBySig | MethodAttributes.Private, typeSystem.Void); var disposingParameter = new ParameterDefinition("disposing", ParameterAttributes.None, typeSystem.Boolean); DisposeBoolMethod.Parameters.Add(disposingParameter); var instructions = DisposeBoolMethod.Body.Instructions; instructions.Add(TypeProcessor.GetDisposeEscapeInstructions()); var skipDisposeManaged = Instruction.Create(OpCodes.Nop); instructions.Add( Instruction.Create(OpCodes.Ldarg, disposingParameter), Instruction.Create(OpCodes.Brfalse, skipDisposeManaged), Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Call, DisposeManagedMethod), skipDisposeManaged, Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Call, DisposeUnmanagedMethod) ); instructions.Add(TypeProcessor.GetDisposedInstructions()); instructions.Add(Instruction.Create(OpCodes.Ret)); TypeProcessor.TargetType.Methods.Add(DisposeBoolMethod); }
public bool IsSecurityCritical (MethodDefinition method) { string entry = method.GetFullName (); if (critical.Contains (entry)) return true; TypeDefinition type = method.DeclaringType; if (!IsSecurityCritical (type)) return false; switch (method.Name) { // e.g. everything we override from System.Object (which is transparent) case "Equals": return (method.Parameters.Count != 1 || method.Parameters [0].ParameterType.FullName != "System.Object"); case "Finalize": case "GetHashCode": case "ToString": return method.HasParameters; // e.g. some transparent interfaces, like IDisposable (implicit or explicit) // downgrade some SC into SSC to respect the override/inheritance rules case "System.IDisposable.Dispose": case "Dispose": return method.HasParameters; default: return true; } }
public bool IsAssertMethod(MethodDefinition method, out int usefulParameters) { SafeDebug.AssumeNotNull(method, "method"); TypeDefinition type; if (method.TryGetDeclaringType(out type)) { if (type.SerializableName == NUnitTestFrameworkMetadata.AssertTypeDefinition) { switch (method.ShortName) { case "IsEmpty": case "IsNotEmpty": case "False": case "IsFalse": case "True": case "IsTrue": case "IsAssignableFrom": case "IsNotAssignableFrom": case "IsNull": case "IsNotNull": case "Null": case "NotNull": case "IsNotNullOrEmpty": case "IsNullOrEmpty": case "IsNan": case "IsInstanceOf": //not entirely correct case "IsNotInstanceOf": //not entirely correct usefulParameters = 1; return true; case "AreEqual": case "AssertDoublesAreEqual": case "AreNotEqual": case "Contains": case "AreSame": case "AreNotSame": case "Greater": case "GreaterOrEqual": case "Less": case "LessOrEqual": usefulParameters = 2; return true; } } else if (type.SerializableName == NUnitTestFrameworkMetadata.CollectionAssertTypeDefinition) { switch (method.ShortName) { case "Equals": case "ReferenceEquals": usefulParameters = -1; return false; default: usefulParameters = 0; return true; } } } usefulParameters = -1; return false; }
static FieldDefinition GetSingleField(PropertyDefinition property, Code code, MethodDefinition methodDefinition) { if (methodDefinition?.Body == null) { return null; } FieldReference fieldReference = null; foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.OpCode.Code == code) { //if fieldReference is not null then we are at the second one if (fieldReference != null) { return null; } var field = instruction.Operand as FieldReference; if (field != null) { if (field.DeclaringType != property.DeclaringType) { continue; } if (field.FieldType != property.PropertyType) { continue; } fieldReference = field; } } } return fieldReference?.Resolve(); }
public void FindInterceptor() { var errorHandler = types.FirstOrDefault(x => x.Name == "MethodTimeLogger"); if (errorHandler == null) { return; } LogMethod = errorHandler.Methods.FirstOrDefault(x => x.Name == "Log"); if (LogMethod == null) { throw new WeavingException(string.Format("Could not find 'Log' method on '{0}'.", errorHandler.FullName)); } if (!LogMethod.IsPublic) { throw new WeavingException("Method 'MethodTimeLogger.Log' is not public."); } if (!LogMethod.IsStatic) { throw new WeavingException("Method 'MethodTimeLogger.Log' is not static."); } var parameters = LogMethod.Parameters; if (parameters.Count != 2) { throw new WeavingException("Method 'MethodTimeLogger.Log' must have 2 parameters of type 'System.Reflection.MethodBase' and 'System.Int64'."); } if (parameters[0].ParameterType.FullName != "System.Reflection.MethodBase") { throw new WeavingException("Method 'MethodTimeLogger.Log' must have 2 parameters of type 'System.Reflection.MethodBase' and 'System.Int64'."); } if (parameters[1].ParameterType.FullName != "System.Int64") { throw new WeavingException("Method 'MethodTimeLogger.Log' must have 2 parameters of type 'System.Reflection.MethodBase' and 'System.Int64'."); } }
public AttributeFinder(MethodDefinition method) { var customAttributes = method.CustomAttributes; if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToDebugOnExceptionAttribute")) { FoundDebug = true; Found = true; } if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToInfoOnExceptionAttribute")) { FoundInfo = true; Found = true; } if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToWarnOnExceptionAttribute")) { FoundWarn = true; Found = true; } if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToErrorOnExceptionAttribute")) { FoundError = true; Found = true; } if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToFatalOnExceptionAttribute")) { FoundFatal = true; Found = true; } if (customAttributes.ContainsAttribute("Anotar.CommonLogging.LogToTraceOnExceptionAttribute")) { FoundTrace = true; Found = true; } }
public override void ProcessMethod(MethodDefinition method) { ProcessExports(method); }
private void DumpMethod(string signature, MethodDefinition method) { var name = "Function" + GetSignature(method, SignatureMode.Name); var delegateSignature = GetSignature(method, SignatureMode.Delegate); var caseArgumentsBuilder = new StringBuilder(); var delegateCallArgs = new StringBuilder(); int argumentCount = 0; int argOffset = 0; for (var i = 0; i < method.Parameters.Count; i++) { var arg = method.Parameters[i]; var type = arg.ParameterType; if (type.Name == "TemplateContext" || type.Name == "SourceSpan") { argOffset++; continue; } argumentCount++; } int argIndex = 0; for (var paramIndex = 0; paramIndex < method.Parameters.Count; paramIndex++) { var arg = method.Parameters[paramIndex]; var type = arg.ParameterType; if (paramIndex > 0) { delegateCallArgs.Append(", "); } if (type.Name == "TemplateContext") { delegateCallArgs.Append("context"); continue; } if (type.Name == "SourceSpan") { delegateCallArgs.Append("callerContext.Span"); continue; } caseArgumentsBuilder.AppendLine($" var arg{argIndex} = ({PrettyType(type)})arguments[{argIndex}];"); delegateCallArgs.Append($"arg{argIndex}"); argIndex++; } var template = $@" /// <summary> /// Optimized custom function for: {signature} /// </summary> private partial class {name} : DynamicCustomFunction {{ private delegate {delegateSignature}; private readonly InternalDelegate _delegate; public {name}(MethodInfo method) : base(method) {{ _delegate = (InternalDelegate)method.CreateDelegate(typeof(InternalDelegate)); }} public override object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, ScriptBlockStatement blockStatement) {{ {caseArgumentsBuilder} return _delegate({delegateCallArgs}); }} }} "; _writer.Write(template); }
public MethodBody(MethodDefinition method) { this.method = method; }
protected abstract ValueNode GetMethodParameterValue(MethodDefinition method, int parameterIndex);
public void Scan(MethodBody methodBody) { MethodDefinition thisMethod = methodBody.Method; Dictionary <VariableDefinition, ValueBasicBlockPair> locals = new Dictionary <VariableDefinition, ValueBasicBlockPair> (methodBody.Variables.Count); Dictionary <int, Stack <StackSlot> > knownStacks = new Dictionary <int, Stack <StackSlot> > (); Stack <StackSlot> currentStack = new Stack <StackSlot> (methodBody.MaxStackSize); ScanExceptionInformation(knownStacks, methodBody); BasicBlockIterator blockIterator = new BasicBlockIterator(methodBody); MethodReturnValue = null; foreach (Instruction operation in methodBody.Instructions) { int curBasicBlock = blockIterator.MoveNext(operation); if (knownStacks.ContainsKey(operation.Offset)) { if (currentStack == null) { // The stack copy constructor reverses the stack currentStack = new Stack <StackSlot> (knownStacks[operation.Offset].Reverse()); } else { currentStack = MergeStack(currentStack, knownStacks[operation.Offset]); } } if (currentStack == null) { currentStack = new Stack <StackSlot> (methodBody.MaxStackSize); } switch (operation.OpCode.Code) { case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.And: case Code.Div: case Code.Div_Un: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Or: case Code.Rem: case Code.Rem_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Xor: case Code.Cgt: case Code.Cgt_Un: case Code.Clt: case Code.Clt_Un: case Code.Shl: case Code.Shr: case Code.Shr_Un: case Code.Ceq: PopUnknown(currentStack, 2, methodBody, operation.Offset); PushUnknown(currentStack); break; case Code.Dup: currentStack.Push(currentStack.Peek()); break; case Code.Ldnull: currentStack.Push(new StackSlot(NullValue.Instance)); break; case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: { int value = operation.OpCode.Code - Code.Ldc_I4_0; ConstIntValue civ = new ConstIntValue(value); StackSlot slot = new StackSlot(civ); currentStack.Push(slot); } break; case Code.Ldc_I4_M1: { ConstIntValue civ = new ConstIntValue(-1); StackSlot slot = new StackSlot(civ); currentStack.Push(slot); } break; case Code.Ldc_I4: { int value = (int)operation.Operand; ConstIntValue civ = new ConstIntValue(value); StackSlot slot = new StackSlot(civ); currentStack.Push(slot); } break; case Code.Ldc_I4_S: { int value = (sbyte)operation.Operand; ConstIntValue civ = new ConstIntValue(value); StackSlot slot = new StackSlot(civ); currentStack.Push(slot); } break; case Code.Arglist: case Code.Ldftn: case Code.Sizeof: case Code.Ldc_I8: case Code.Ldc_R4: case Code.Ldc_R8: PushUnknown(currentStack); break; case Code.Ldarg: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarg_S: case Code.Ldarga: case Code.Ldarga_S: ScanLdarg(operation, currentStack, thisMethod, methodBody); break; case Code.Ldloc: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldloc_S: case Code.Ldloca: case Code.Ldloca_S: ScanLdloc(operation, currentStack, methodBody, locals); break; case Code.Ldstr: { StackSlot slot = new StackSlot(new KnownStringValue((string)operation.Operand)); currentStack.Push(slot); } break; case Code.Ldtoken: ScanLdtoken(operation, currentStack); break; case Code.Ldind_I: case Code.Ldind_I1: case Code.Ldind_I2: case Code.Ldind_I4: case Code.Ldind_I8: case Code.Ldind_R4: case Code.Ldind_R8: case Code.Ldind_U1: case Code.Ldind_U2: case Code.Ldind_U4: case Code.Ldlen: case Code.Ldvirtftn: case Code.Localloc: case Code.Refanytype: case Code.Refanyval: case Code.Conv_I1: case Code.Conv_I2: case Code.Conv_I4: case Code.Conv_Ovf_I1: case Code.Conv_Ovf_I1_Un: case Code.Conv_Ovf_I2: case Code.Conv_Ovf_I2_Un: case Code.Conv_Ovf_I4: case Code.Conv_Ovf_I4_Un: case Code.Conv_Ovf_U: case Code.Conv_Ovf_U_Un: case Code.Conv_Ovf_U1: case Code.Conv_Ovf_U1_Un: case Code.Conv_Ovf_U2: case Code.Conv_Ovf_U2_Un: case Code.Conv_Ovf_U4: case Code.Conv_Ovf_U4_Un: case Code.Conv_U1: case Code.Conv_U2: case Code.Conv_U4: case Code.Conv_I8: case Code.Conv_Ovf_I8: case Code.Conv_Ovf_I8_Un: case Code.Conv_Ovf_U8: case Code.Conv_Ovf_U8_Un: case Code.Conv_U8: case Code.Conv_I: case Code.Conv_Ovf_I: case Code.Conv_Ovf_I_Un: case Code.Conv_U: case Code.Conv_R_Un: case Code.Conv_R4: case Code.Conv_R8: case Code.Ldind_Ref: case Code.Ldobj: case Code.Mkrefany: case Code.Unbox: case Code.Unbox_Any: case Code.Box: case Code.Neg: case Code.Not: PopUnknown(currentStack, 1, methodBody, operation.Offset); PushUnknown(currentStack); break; case Code.Isinst: case Code.Castclass: // We can consider a NOP because the value doesn't change. // It might change to NULL, but for the purposes of dataflow analysis // it doesn't hurt much. break; case Code.Ldfld: case Code.Ldsfld: case Code.Ldflda: case Code.Ldsflda: ScanLdfld(operation, currentStack, thisMethod, methodBody); break; case Code.Newarr: { StackSlot count = PopUnknown(currentStack, 1, methodBody, operation.Offset); currentStack.Push(new StackSlot(new ArrayValue(count.Value, (TypeReference)operation.Operand))); } break; case Code.Stelem_I: case Code.Stelem_I1: case Code.Stelem_I2: case Code.Stelem_I4: case Code.Stelem_I8: case Code.Stelem_R4: case Code.Stelem_R8: case Code.Stelem_Any: case Code.Stelem_Ref: ScanStelem(operation, currentStack, methodBody, curBasicBlock); break; case Code.Ldelem_I: case Code.Ldelem_I1: case Code.Ldelem_I2: case Code.Ldelem_I4: case Code.Ldelem_I8: case Code.Ldelem_R4: case Code.Ldelem_R8: case Code.Ldelem_U1: case Code.Ldelem_U2: case Code.Ldelem_U4: case Code.Ldelem_Any: case Code.Ldelem_Ref: case Code.Ldelema: ScanLdelem(operation, currentStack, methodBody, curBasicBlock); break; case Code.Cpblk: case Code.Initblk: PopUnknown(currentStack, 3, methodBody, operation.Offset); break; case Code.Stfld: case Code.Stsfld: ScanStfld(operation, currentStack, thisMethod, methodBody); break; case Code.Cpobj: PopUnknown(currentStack, 2, methodBody, operation.Offset); break; case Code.Stind_I: case Code.Stind_I1: case Code.Stind_I2: case Code.Stind_I4: case Code.Stind_I8: case Code.Stind_R4: case Code.Stind_R8: case Code.Stind_Ref: case Code.Stobj: ScanIndirectStore(operation, currentStack, methodBody); break; case Code.Initobj: case Code.Pop: PopUnknown(currentStack, 1, methodBody, operation.Offset); break; case Code.Starg: case Code.Starg_S: ScanStarg(operation, currentStack, thisMethod, methodBody); break; case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: ScanStloc(operation, currentStack, methodBody, locals, curBasicBlock); break; case Code.Constrained: case Code.No: case Code.Readonly: case Code.Tail: case Code.Unaligned: case Code.Volatile: break; case Code.Brfalse: case Code.Brfalse_S: case Code.Brtrue: case Code.Brtrue_S: PopUnknown(currentStack, 1, methodBody, operation.Offset); NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, currentStack); break; case Code.Calli: { var signature = (CallSite)operation.Operand; if (signature.HasThis && !signature.ExplicitThis) { PopUnknown(currentStack, 1, methodBody, operation.Offset); } // Pop arguments if (signature.Parameters.Count > 0) { PopUnknown(currentStack, signature.Parameters.Count, methodBody, operation.Offset); } // Pop function pointer PopUnknown(currentStack, 1, methodBody, operation.Offset); if (GetReturnTypeWithoutModifiers(signature.ReturnType).MetadataType != MetadataType.Void) { PushUnknown(currentStack); } } break; case Code.Call: case Code.Callvirt: case Code.Newobj: HandleCall(methodBody, operation, currentStack, curBasicBlock); break; case Code.Jmp: // Not generated by mainstream compilers break; case Code.Br: case Code.Br_S: NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, currentStack); ClearStack(ref currentStack); break; case Code.Leave: case Code.Leave_S: ClearStack(ref currentStack); NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, new Stack <StackSlot> (methodBody.MaxStackSize)); break; case Code.Endfilter: case Code.Endfinally: case Code.Rethrow: case Code.Throw: ClearStack(ref currentStack); break; case Code.Ret: { bool hasReturnValue = GetReturnTypeWithoutModifiers(methodBody.Method.ReturnType).MetadataType != MetadataType.Void; if (currentStack.Count != (hasReturnValue ? 1 : 0)) { WarnAboutInvalidILInMethod(methodBody, operation.Offset); } if (hasReturnValue) { StackSlot retValue = PopUnknown(currentStack, 1, methodBody, operation.Offset); MethodReturnValue = MergePointValue.MergeValues(MethodReturnValue, retValue.Value); } ClearStack(ref currentStack); break; } case Code.Switch: { PopUnknown(currentStack, 1, methodBody, operation.Offset); Instruction[] targets = (Instruction[])operation.Operand; foreach (Instruction target in targets) { NewKnownStack(knownStacks, target.Offset, currentStack); } break; } case Code.Beq: case Code.Beq_S: case Code.Bne_Un: case Code.Bne_Un_S: case Code.Bge: case Code.Bge_S: case Code.Bge_Un: case Code.Bge_Un_S: case Code.Bgt: case Code.Bgt_S: case Code.Bgt_Un: case Code.Bgt_Un_S: case Code.Ble: case Code.Ble_S: case Code.Ble_Un: case Code.Ble_Un_S: case Code.Blt: case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: PopUnknown(currentStack, 2, methodBody, operation.Offset); NewKnownStack(knownStacks, ((Instruction)operation.Operand).Offset, currentStack); break; } } }
public static void Patch(AssemblyDefinition assembly) { string hookloc = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); //load hook AssemblyDefinition hookDefinition = AssemblyLoader.LoadAssembly(Path.Combine(hookloc, $"{HOOK_NAME}.dll")); TypeDefinition catmanager = hookDefinition.MainModule.GetType($"{HOOK_NAME}.catmanager"); // add model slots TypeDefinition tbody = assembly.MainModule.GetType("TBody"); TypeDefinition tslotid = tbody.NestedTypes.First(t => t.Name == "SlotID"); //remove IsInitOnly attribute from m_strDefSlotName FieldDefinition defslot = tbody.GetField("m_strDefSlotName"); defslot.IsInitOnly = false; // extend m_strDefSlotName MethodDefinition slotext = catmanager.GetMethod("slotext"); MethodDefinition TbodyInit = tbody.GetMethod("Init"); TbodyInit.InjectWith(slotext); //remove "end" field tslotid.Fields.RemoveAt(59); fieldgen(SlotID, 58, tslotid); //add "end" field back. not sure if there is a point in messing with end field, but i can't be bothered checking fieldgen2("end", 76, tslotid); // add MPN TypeDefinition maid = assembly.MainModule.GetType("Maid"); TypeDefinition mpn = assembly.MainModule.GetType("MPN"); MethodDefinition CreateInitMaidPropList = maid.GetMethod("CreateInitMaidPropList"); MethodDefinition maidpropext = catmanager.GetMethod("maidpropext"); CreateInitMaidPropList.InjectWith(maidpropext, flags: InjectFlags.ModifyReturn); fieldgen(MPNarry, 88, mpn); //fix mpn update MethodDefinition AllProcProp = maid.GetMethod("AllProcProp"); MethodDefinition AllProcExt = catmanager.GetMethod("AllProcExt"); MethodDefinition AllProcSeqExt = catmanager.GetMethod("AllProcSeqExt"); MethodDefinition AllProcPropSeq = maid.GetMethod("AllProcPropSeq"); //extend loop within Maid.AllProcProp() int counter = 0; for (int instn = 0; instn < AllProcProp.Body.Instructions.Count; instn++) { if (AllProcProp.Body.Instructions[instn].OpCode == OpCodes.Add) { { AllProcProp.InjectWith(AllProcExt, codeOffset: instn - 2, flags: InjectFlags.PassInvokingInstance | InjectFlags.PassLocals, localsID: new[] { 2 }); break; } } } //extend loop within Maid.AllProcPropSeq() for (int instn = 0; instn < AllProcPropSeq.Body.Instructions.Count; instn++) { if (AllProcPropSeq.Body.Instructions[instn].OpCode == OpCodes.Br) { counter += 1; if (counter == 5) { AllProcPropSeq.InjectWith(AllProcSeqExt, codeOffset: instn, flags: InjectFlags.PassInvokingInstance | InjectFlags.PassLocals, localsID: new[] { 0 }); break; } } } // expand PresetSetp reads //target definition TypeDefinition charactermgr = assembly.MainModule.GetType("CharacterMgr"); MethodDefinition setpreset = charactermgr.GetMethod("PresetSet"); // inject method definition MethodDefinition ExtSet = catmanager.GetMethod("ExtSet"); setpreset.InjectWith(ExtSet, flags: InjectFlags.PassParametersVal); // add del menus to dictionaryy. mostly OCD thing. // this kinda redundant as same can be doen with addition comands in del menus themselves, but whatever TypeDefinition CM3 = assembly.MainModule.GetType("CM3"); MethodDefinition CM3_cctor = CM3.GetMethod(".cctor"); MethodDefinition delmenuadder = catmanager.GetMethod("delmenuadder"); CM3_cctor.InjectWith(delmenuadder, -1); //add categories to the list TypeDefinition sceneEditInfo = assembly.MainModule.GetType("SceneEditInfo"); MethodDefinition loadCustom = catmanager.GetMethod("loadcustomcats"); MethodDefinition SE_cctor = sceneEditInfo.GetMethod(".cctor"); SE_cctor.InjectWith(loadCustom, -1); // extend EMenuPartsType // this is rather unnecessary, as it's possible to use existing MPN of diffferent type, but it's less headache this way. TypeDefinition EMenuPartsType = sceneEditInfo.NestedTypes.First(t => t.Name == "EMenuPartsType"); fieldgen(MPNarry, 50, EMenuPartsType); // add body to EMenuPartsType fieldgen2("body", 68, EMenuPartsType); }
/// <summary> /// Writes a CIL method body, analyzes it as Flame IR /// and checks that the result is what we'd expect. /// </summary> /// <param name="returnType"> /// The return type of the method body. /// </param> /// <param name="parameterTypes"> /// The parameter types of the method body. /// </param> /// <param name="emitBody"> /// A function that writes the method body. /// </param> /// <param name="oracle"> /// The expected Flame IR flow graph, as LESv2. /// </param> private void AnalyzeStaticMethodBody( TypeReference returnType, IReadOnlyList <TypeReference> parameterTypes, IReadOnlyList <TypeReference> localTypes, Action <Mono.Cecil.Cil.ILProcessor> emitBody, string oracle) { var methodDef = new MethodDefinition( "f", MethodAttributes.Public | MethodAttributes.Static, returnType); foreach (var type in parameterTypes) { methodDef.Parameters.Add(new ParameterDefinition(type)); int index = methodDef.Parameters.Count - 1; methodDef.Parameters[index].Name = "param_" + index; } var cilBody = new Mono.Cecil.Cil.MethodBody(methodDef); foreach (var localType in localTypes) { cilBody.Variables.Add(new Mono.Cecil.Cil.VariableDefinition(localType)); } emitBody(cilBody.GetILProcessor()); var irBody = ClrMethodBodyAnalyzer.Analyze( cilBody, new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(returnType))), default(Parameter), parameterTypes .Select((type, i) => new Parameter(TypeHelpers.BoxIfReferenceType(corlib.Resolve(type)), "param_" + i)) .ToArray(), corlib); var encoder = new EncoderState(); var encodedImpl = encoder.Encode(irBody.Implementation); var actual = Les2LanguageService.Value.Print( encodedImpl, options: new LNodePrinterOptions { IndentString = new string(' ', 4) }); if (actual.Trim() != oracle.Trim()) { log.Log( new LogEntry( Severity.Message, "CIL analysis-oracle mismatch", "analyzed CIL does not match the oracle. CIL analysis output:")); // TODO: ugly hack to work around wrapping. Console.Error.WriteLine(actual.Trim()); } Assert.AreEqual( actual.Trim(), oracle.Trim()); }
private static void CopyMethodContents( MethodDefinition sourceMethod, MethodDefinition targetMethod, Dictionary <IMemberDefinition, IMemberDefinition> memberMap) { var targetModule = targetMethod.Module; foreach (var paramDef in sourceMethod.Parameters) { targetMethod.Parameters.Add(new ParameterDefinition(memberMap.Find(paramDef.ParameterType) as TypeReference ?? targetModule.ImportReference(paramDef.ParameterType))); } foreach (var varDef in sourceMethod.Body.Variables) { targetMethod.Body.Variables.Add(new VariableDefinition(memberMap.Find(varDef.VariableType) as TypeReference ?? targetModule.ImportReference(varDef.VariableType))); targetMethod.Body.InitLocals = true; } foreach (var instr in sourceMethod.Body.Instructions) { //var newInstruction = new Instruction(instr.OpCode, instr.Operand); var constructorInfo = typeof(Instruction).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(OpCode), typeof(object) }, null); var newInstr = (Instruction)constructorInfo.Invoke(new[] { instr.OpCode, instr.Operand }); var fieldRef = newInstr.Operand as FieldReference; if (fieldRef != null) { newInstr.Operand = memberMap.Find(fieldRef) as FieldReference ?? targetModule.ImportReference(fieldRef); } var methodRef = newInstr.Operand as MethodReference; if (methodRef != null) { newInstr.Operand = memberMap.Find(methodRef) as MethodReference ?? targetModule.ImportReference(methodRef); } var typeRef = newInstr.Operand as TypeReference; if (typeRef != null) { newInstr.Operand = memberMap.Find(typeRef) as TypeReference ?? targetModule.ImportReference(typeRef); } targetMethod.Body.Instructions.Add(newInstr); } foreach (var handler in sourceMethod.Body.ExceptionHandlers) { var newHandler = new ExceptionHandler(handler.HandlerType); if (handler.CatchType != null) { newHandler.CatchType = memberMap.Find(handler.CatchType) as TypeReference ?? targetModule.ImportReference(handler.CatchType); } if (handler.FilterStart != null) { newHandler.FilterStart = targetMethod.Body.Instructions[sourceMethod.Body.Instructions.IndexOf(handler.FilterStart)]; } if (handler.HandlerEnd != null) { newHandler.HandlerEnd = targetMethod.Body.Instructions[sourceMethod.Body.Instructions.IndexOf(handler.HandlerEnd)]; } if (handler.HandlerStart != null) { newHandler.HandlerStart = targetMethod.Body.Instructions[sourceMethod.Body.Instructions.IndexOf(handler.HandlerStart)]; } if (handler.TryEnd != null) { newHandler.TryEnd = targetMethod.Body.Instructions[sourceMethod.Body.Instructions.IndexOf(handler.TryEnd)]; } if (handler.TryStart != null) { newHandler.TryStart = targetMethod.Body.Instructions[sourceMethod.Body.Instructions.IndexOf(handler.TryStart)]; } targetMethod.Body.ExceptionHandlers.Add(newHandler); } // HACK: maxstack fix - https://github.com/Fody/Fody/issues/257 // Fake an OpCode to set a StackBehaviour of "push" instead of "pop" to trick stack size // computation into thinking there is more stack size used when it really isn't. OpCode pushingPop = (OpCode)typeof(OpCode).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(new object[] { 0xff << 0 | 0x26 << 8 | (byte)Code.Pop << 16 | (byte)FlowControl.Next << 24, (byte)OpCodeType.Primitive << 0 | (byte)OperandType.InlineNone << 8 | (byte)StackBehaviour.Pop0 << 16 | (byte)StackBehaviour.Push1 << 24 }); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(OpCodes.Ldnull)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(OpCodes.Ldnull)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(OpCodes.Ldnull)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(OpCodes.Ldnull)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(pushingPop)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(pushingPop)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(pushingPop)); targetMethod.Body.Instructions.Insert(targetMethod.Body.Instructions.Count - 1, Instruction.Create(pushingPop)); // Fix handlers for inserted instructions var lastInstr = targetMethod.Body.Instructions[targetMethod.Body.Instructions.Count - 1]; foreach (var handler in targetMethod.Body.ExceptionHandlers.Where(h => h.HandlerEnd == lastInstr).ToList()) { handler.HandlerEnd = targetMethod.Body.Instructions[targetMethod.Body.Instructions.Count - 9]; } }
public virtual DialogResult ShowDialog(MethodDefinition mdef, ExceptionHandler selected) { MethodDefinition = mdef; SelectedExceptionHandler = selected; return(ShowDialog()); }
public CustomAttribute CompilerGenerated() { MethodDefinition constructor = _wellKnownTypes.SystemRuntimeCompilerServicesCompilerGeneratedAttribute.Resolve().Methods.Single(method => method.IsConstructor && !method.IsStatic && method.Parameters.Count == 0); return(new CustomAttribute(_wellKnownTypes.Module.ImportReference(constructor))); }
private bool MatchMethod(MethodDefinition method) { return(method.Name.Contains(FilteredName)); }
private static void Fix(MethodDefinition meth) { foreach (var obj in meth.Parameters) { if (!MatchesPlatform(obj.ParameterType)) { obj.ParameterType = ReferenceResolver.Fix(meth.Module, obj.ParameterType); } } if (!MatchesPlatform(meth.MethodReturnType.ReturnType)) { meth.MethodReturnType.ReturnType = ReferenceResolver.Fix( meth.Module, meth.MethodReturnType.ReturnType); } for (var i = 0; i < meth.Overrides.Count; ++i) { meth.Overrides[i] = ReferenceResolver.Fix(meth.Module, meth.Overrides[i]); } if (!meth.HasBody || meth.Body == null) { return; } if (meth.Body.ThisParameter != null && !MatchesPlatform(meth.Body.ThisParameter.ParameterType)) { meth.Body.ThisParameter.ParameterType = ReferenceResolver.Fix( meth.Module, meth.Body.ThisParameter.ParameterType); } if (meth.Body.HasVariables) { foreach (var v in meth.Body.Variables) { v.VariableType = ReferenceResolver.Fix(meth.Module, v.VariableType); } } foreach (var insn in meth.Body.Instructions) { var oper = insn.Operand; var asType = oper as TypeReference; var asMeth = oper as MethodReference; var asField = oper as FieldReference; var asVar = oper as VariableDefinition; var asParam = oper as ParameterDefinition; var asCall = oper as CallSite; if (asType != null) { insn.Operand = ReferenceResolver.Fix(meth.Module, asType); } else if (asMeth != null) { insn.Operand = ReferenceResolver.Fix(meth.Module, asMeth); } else if (asField != null) { insn.Operand = ReferenceResolver.Fix(meth.Module, asField); } else if (asVar != null) { asVar.VariableType = ReferenceResolver.Fix(meth.Module, asVar.VariableType); } else if (asParam != null) { asParam.ParameterType = ReferenceResolver.Fix(meth.Module, asParam.ParameterType); } else if (asCall != null) { foreach (var param in asCall.Parameters) { param.ParameterType = ReferenceResolver.Fix(meth.Module, param.ParameterType); } asCall.ReturnType = ReferenceResolver.Fix(meth.Module, asCall.ReturnType); } } }
/// <summary> /// Extracts the method signature from the metadata by rid /// </summary> public ReadyToRunMethod( ReadyToRunReader readyToRunReader, IAssemblyMetadata componentReader, EntityHandle methodHandle, int entryPointId, string owningType, string constrainedType, string[] instanceArgs, int?fixupOffset) { _readyToRunReader = readyToRunReader; _fixupOffset = fixupOffset; MethodHandle = methodHandle; EntryPointRuntimeFunctionId = entryPointId; ComponentReader = componentReader; EntityHandle owningTypeHandle; GenericParameterHandleCollection genericParams = default(GenericParameterHandleCollection); DisassemblingGenericContext genericContext = new DisassemblingGenericContext(typeParameters: Array.Empty <string>(), methodParameters: instanceArgs); DisassemblingTypeProvider typeProvider = new DisassemblingTypeProvider(); // get the method signature from the method handle switch (MethodHandle.Kind) { case HandleKind.MethodDefinition: { MethodDefinition methodDef = ComponentReader.MetadataReader.GetMethodDefinition((MethodDefinitionHandle)MethodHandle); if (methodDef.RelativeVirtualAddress != 0) { MethodBodyBlock mbb = ComponentReader.ImageReader.GetMethodBody(methodDef.RelativeVirtualAddress); if (!mbb.LocalSignature.IsNil) { StandaloneSignature ss = ComponentReader.MetadataReader.GetStandaloneSignature(mbb.LocalSignature); LocalSignature = ss.DecodeLocalSignature(typeProvider, genericContext); } } Name = ComponentReader.MetadataReader.GetString(methodDef.Name); Signature = methodDef.DecodeSignature <string, DisassemblingGenericContext>(typeProvider, genericContext); owningTypeHandle = methodDef.GetDeclaringType(); genericParams = methodDef.GetGenericParameters(); } break; case HandleKind.MemberReference: { MemberReference memberRef = ComponentReader.MetadataReader.GetMemberReference((MemberReferenceHandle)MethodHandle); Name = ComponentReader.MetadataReader.GetString(memberRef.Name); Signature = memberRef.DecodeMethodSignature <string, DisassemblingGenericContext>(typeProvider, genericContext); owningTypeHandle = memberRef.Parent; } break; default: throw new NotImplementedException(); } if (owningType != null) { DeclaringType = owningType; } else { DeclaringType = MetadataNameFormatter.FormatHandle(ComponentReader.MetadataReader, owningTypeHandle); } StringBuilder sb = new StringBuilder(); sb.Append(Signature.ReturnType); sb.Append(" "); sb.Append(DeclaringType); sb.Append("."); sb.Append(Name); if (Signature.GenericParameterCount != 0) { sb.Append("<"); for (int i = 0; i < Signature.GenericParameterCount; i++) { if (i > 0) { sb.Append(", "); } if (instanceArgs != null && instanceArgs.Length > i) { sb.Append(instanceArgs[i]); } else { sb.Append("!"); sb.Append(i); } } sb.Append(">"); } sb.Append("("); for (int i = 0; i < Signature.ParameterTypes.Length; i++) { if (i > 0) { sb.Append(", "); } sb.AppendFormat($"{Signature.ParameterTypes[i]}"); } sb.Append(")"); SignatureString = sb.ToString(); }
private void SetMethodToVirtual(MethodDefinition meth) { meth.IsVirtual = true; }
public MethodReference InjectEqualsInternal(TypeDefinition type, TypeReference typeRef, MethodDefinition collectionEquals, bool ignoreBaseClassProperties) { var methodAttributes = MethodAttributes.Private | MethodAttributes.HideBySig | MethodAttributes.Static; var method = new MethodDefinition("EqualsInternal", methodAttributes, TypeSystem.BooleanReference); MarkAsGeneratedCode(method.CustomAttributes); var left = method.Parameters.Add("left", typeRef); var right = method.Parameters.Add("right", typeRef); var body = method.Body; body.InitLocals = true; var ins = body.Instructions; var properties = type.GetPropertiesWithoutIgnores(ignoreDuringEqualsAttributeName); if (ignoreBaseClassProperties) { properties = properties.IgnoreBaseClassProperties(type); } foreach (var property in properties) { AddPropertyCode(type, collectionEquals, property, ins, left, right); } var methods = type.GetMethods(); var customLogic = methods .Where(x => x.CustomAttributes.Any(y => y.AttributeType.Name == customEqualsInternalAttribute)).ToArray(); if (customLogic.Length > 2) { throw new WeavingException("Only one custom method can be specified."); } if (customLogic.Length == 1) { AddCustomLogicCall(type, body, ins, customLogic); } ins.AddReturnTrue(); body.OptimizeMacros(); type.Methods.AddOrReplace(method); var methodToCall = new MethodReference(method.Name, method.ReturnType, typeRef); foreach (var parameter in method.Parameters) { methodToCall.Parameters.Add(parameter); } return(methodToCall); }
public static string Show(this MethodDefinition method) => $"{method.ReturnType.Show()} {method.Name}{method.GenericParameters.Show()}{method.Parameters.Show('(', ')', true)}";
private void SetMethodToPublic(MethodDefinition field) { field.IsFamily = false; field.IsPrivate = false; field.IsPublic = true; }
public void Execute() { var markerDll = Check(() => ModuleDefinition.AssemblyReferences.SingleOrDefault(a => a.Name.ToLowerInvariant() == "AutoDependencyPropertyMarker".ToLowerInvariant()), "find AutoDependencyPropertyMarker reference"); if (markerDll == null) { return; } var windowsBase = Check(() => ModuleDefinition.AssemblyResolver.Resolve(ModuleDefinition.AssemblyReferences.Single(a => a.Name.ToLowerInvariant() == "WindowsBase".ToLowerInvariant())).MainModule, "find 'WindowsBase reference'. Add a reference to any Type in this Assembly to your own code."); var mscorlib = CheckAssembly("mscorlib"); var typeFromHandle = CheckImport(() => mscorlib.GetType("System.Type").Methods.Single(m => m.Name == "GetTypeFromHandle"), "GetTypeFromHandle"); var depObject = Check(() => windowsBase.GetType("System.Windows.DependencyObject"), "load DependencyObject"); var getValue = CheckImport(() => depObject.Methods.Single(m => m.Name == "GetValue"), "GetValue"); var setValue = CheckImport(() => depObject.Methods.Single(m => m.Name == "SetValue" && m.Parameters.Count == 2 && m.Parameters[0].ParameterType.Name == "DependencyProperty" && m.Parameters[1].ParameterType.Name == "Object"), "SetValue"); var depProperty = Check(() => windowsBase.GetType("System.Windows.DependencyProperty"), "load DependencyProperty"); var depPropertyRef = Check(() => ModuleDefinition.Import(depProperty), "import DependencyProperty"); var registerSimple = CheckImport(() => depProperty.Methods.Single(m => m.Name == "Register" && m.Parameters.Count == 3), "Register"); var registerMeta = CheckImport(() => depProperty.Methods.Single(m => m.Name == "Register" && m.Parameters.Count == 4), "Register"); var presentationDllRef = Check(() => ModuleDefinition.AssemblyReferences.SingleOrDefault(a => a.Name.ToLowerInvariant() == "PresentationFramework".ToLowerInvariant()), "check for PresentationFramework reference"); MethodReference metadataCtor = null; foreach (var type in ModuleDefinition.Types) { if (!type.IsSpecialName && type.GenericParameters.Count == 0 && Inherits(type, "System.Windows.DependencyObject")) { var instructions = new List <Instruction>(); var cctor = type.GetStaticConstructor(); foreach (var property in type.Properties) { if (!property.IsSpecialName && property.HasThis && property.GetMethod != null && property.SetMethod != null && property.GetMethod.IsPublic && property.SetMethod.IsPublic) { var attribute = property.CustomAttributes.Concat(type.CustomAttributes).FirstOrDefault( a => a.AttributeType.FullName == "AutoDependencyPropertyMarker.AutoDependencyPropertyAttribute"); if (attribute == null) { continue; } if (type.Fields.Any(f => f.Name == property.Name + "Property")) { continue; } var backing = type.Fields.FirstOrDefault(f => f.Name == "<" + property.Name + ">k__BackingField" && f.FieldType.FullName == property.PropertyType.FullName); if (backing == null) { continue; } var field = new FieldDefinition(property.Name + "Property", FieldAttributes.Static | FieldAttributes.InitOnly | FieldAttributes.Public, depPropertyRef); type.Fields.Add(field); if (cctor == null) { cctor = new MethodDefinition(".cctor", MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Private | MethodAttributes.RTSpecialName, ModuleDefinition.TypeSystem.Void); type.Methods.Add(cctor); cctor.Body.Instructions.Add(Instruction.Create(OpCodes.Ret)); } instructions.Add(Instruction.Create(OpCodes.Ldstr, property.Name)); instructions.Add(Instruction.Create(OpCodes.Ldtoken, property.PropertyType)); instructions.Add(Instruction.Create(OpCodes.Call, typeFromHandle)); instructions.Add(Instruction.Create(OpCodes.Ldtoken, type)); instructions.Add(Instruction.Create(OpCodes.Call, typeFromHandle)); var options = attribute.Properties.FirstOrDefault(p => p.Name == "Options"); if (options.Name == null || (int)options.Argument.Value == 0) { instructions.Add(Instruction.Create(OpCodes.Call, registerSimple)); } else { if (metadataCtor == null) { if (presentationDllRef == null) { metadataCtor = Check(() => ModuleDefinition.Import(typeof(FrameworkPropertyMetadata).GetConstructor(new[] { typeof(object), typeof(FrameworkPropertyMetadataOptions) })), "directly import FrameworkPropertyMetadata constructor"); } else { var presentationDll = CheckAssembly("PresentationFramework"); metadataCtor = CheckImport(() => presentationDll.GetType("System.Windows.FrameworkPropertyMetadata").GetConstructors().Single(c => c.Parameters.Count == 2 && c.Parameters[1].ParameterType.Name == "FrameworkPropertyMetadataOptions"), "FrameworkPropertyMetadata constructor"); } } if (!property.PropertyType.IsValueType) { instructions.Add(Instruction.Create(OpCodes.Ldnull)); } else { cctor.Body.InitLocals = true; var constVar = new VariableDefinition(property.PropertyType); cctor.Body.Variables.Add(constVar); instructions.Add(Instruction.Create(OpCodes.Ldloca_S, constVar)); instructions.Add(Instruction.Create(OpCodes.Initobj, property.PropertyType)); instructions.Add(Instruction.Create(OpCodes.Ldloc, constVar)); instructions.Add(Instruction.Create(OpCodes.Box, property.PropertyType)); } instructions.Add(Instruction.Create(OpCodes.Ldc_I4, (int)options.Argument.Value)); instructions.Add(Instruction.Create(OpCodes.Newobj, metadataCtor)); instructions.Add(Instruction.Create(OpCodes.Call, registerMeta)); } instructions.Add(Instruction.Create(OpCodes.Stsfld, field)); property.GetMethod.Body.Instructions.Clear(); var getter = property.GetMethod.Body.GetILProcessor(); getter.Emit(OpCodes.Ldarg_0); getter.Emit(OpCodes.Ldarg_0); getter.Emit(OpCodes.Ldfld, field); getter.Emit(OpCodes.Call, getValue); getter.Emit(property.PropertyType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, property.PropertyType); getter.Emit(OpCodes.Ret); property.SetMethod.Body.Instructions.Clear(); var setter = property.SetMethod.Body.GetILProcessor(); setter.Emit(OpCodes.Ldarg_0); setter.Emit(OpCodes.Ldarg_0); setter.Emit(OpCodes.Ldfld, field); setter.Emit(OpCodes.Ldarg_1); if (property.PropertyType.IsValueType) { setter.Emit(OpCodes.Box, property.PropertyType); } setter.Emit(OpCodes.Call, setValue); setter.Emit(OpCodes.Ret); type.Fields.Remove(backing); property.CustomAttributes.Remove(attribute); } } instructions.Reverse(); foreach (var instruction in instructions) { cctor.Body.Instructions.Insert(0, instruction); } foreach (var attribute in type.CustomAttributes.Where(a => a.AttributeType.FullName == "AutoDependencyPropertyMarker.AutoDependencyPropertyAttribute").ToList()) { type.CustomAttributes.Remove(attribute); } } } ModuleDefinition.AssemblyReferences.Remove(markerDll); }
public AdviceAroundProcess(ILogger log, MethodDefinition target, InjectionDefinition injection) : base(log, target, injection) { _wrapperNamePrefix = $"{GetAroundMethodPrefix(_method)}w_"; _unWrapperName = $"{GetAroundMethodPrefix(_method)}u"; _movedOriginalName = $"{GetAroundMethodPrefix(_method)}o"; }
public virtual string GetInlineCode(MethodDefinition method) { return(this.GetAttributeValue(method.CustomAttributes, Translator.Bridge_ASSEMBLY + ".TemplateAttribute")); }
public virtual void CheckMethodArguments(MethodDefinition method) { }
static int ReadCodeSize(MethodDefinition method) { return(method.Module.Read(method, (m, reader) => reader.ReadCodeSize(m))); }
public virtual bool IsInlineMethod(MethodDefinition method) { var attr = this.GetAttribute(method.CustomAttributes, Translator.Bridge_ASSEMBLY + ".TemplateAttribute"); return(attr != null && !attr.HasConstructorArguments); }
public ManagedCtor(GenBase declaringType, MethodDefinition m) : this(declaringType, m, new ManagedMethodBaseSupport(m)) { }
/// <summary> /// Initializes a new instance of <see cref="ConstructorOverloadDocumentation"/> /// </summary> /// <param name="methodDocumentation">The documentation model of the constructor being overloaded.</param> /// <param name="definition">The definition of the constructor method.</param> /// <param name="xmlDocsProvider">The XML documentation provider to use for loading XML documentation comments.</param> /// <exception cref="ArgumentNullException">Thrown when one of the constructor arguments is null.</exception> internal ConstructorOverloadDocumentation(ConstructorDocumentation methodDocumentation, MethodDefinition definition, IXmlDocsProvider xmlDocsProvider) : base(definition, xmlDocsProvider) { ConstructorDocumentation = methodDocumentation ?? throw new ArgumentNullException(nameof(methodDocumentation)); }
private void ScanLdarg(Instruction operation, Stack <StackSlot> currentStack, MethodDefinition thisMethod, MethodBody methodBody) { Code code = operation.OpCode.Code; bool isByRef; // Thank you Cecil, Operand being a ParameterDefinition instead of an integer, // (except for Ldarg_0 - Ldarg_3, where it's null) makes all of this really convenient... // NOT. int paramNum; if (code >= Code.Ldarg_0 && code <= Code.Ldarg_3) { paramNum = code - Code.Ldarg_0; if (thisMethod.HasImplicitThis()) { if (paramNum == 0) { isByRef = thisMethod.DeclaringType.IsValueType; } else { isByRef = thisMethod.Parameters[paramNum - 1].ParameterType.IsByRefOrPointer(); } } else { isByRef = thisMethod.Parameters[paramNum].ParameterType.IsByRefOrPointer(); } } else { var paramDefinition = (ParameterDefinition)operation.Operand; if (thisMethod.HasImplicitThis()) { if (paramDefinition == methodBody.ThisParameter) { paramNum = 0; } else { paramNum = paramDefinition.Index + 1; } } else { paramNum = paramDefinition.Index; } isByRef = paramDefinition.ParameterType.IsByRefOrPointer(); } isByRef |= code == Code.Ldarga || code == Code.Ldarga_S; StackSlot slot = new StackSlot(GetMethodParameterValue(thisMethod, paramNum), isByRef); currentStack.Push(slot); }
static bool HasXUnitAttributes(MethodDefinition x) { return(HasXunitAttribute(x.CustomAttributes)); }
protected abstract ValueNode GetFieldValue(MethodDefinition method, FieldDefinition field);
public MethodInjector(MethodDefinition method) { _methodBody = method.Body; _ilprocessor = method.Body.GetILProcessor(); }
public virtual void VisitMethodDefinition(MethodDefinition methodDefinitions) { }
void AddGetItem() { var method = new MethodDefinition(DataErrorInfoFinder.InterfaceRef.FullName + ".get_Item", MethodAttributes, TypeSystem.String) { IsGetter = true, IsPrivate = true, SemanticsAttributes = MethodSemanticsAttributes.Getter, }; method.Overrides.Add(DataErrorInfoFinder.GetItemMethod); method.Parameters.Add(new ParameterDefinition(TypeSystem.String)); method.Body.Instructions.Append( Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldfld, ValidationTemplateField), Instruction.Create(OpCodes.Ldarg_1), Instruction.Create(OpCodes.Callvirt, DataErrorInfoFinder.GetItemMethod), Instruction.Create(OpCodes.Ret)); var property = new PropertyDefinition(DataErrorInfoFinder.InterfaceRef.FullName + ".Item", PropertyAttributes.None, TypeSystem.String) { GetMethod = method, }; TypeDefinition.Methods.Add(method); TypeDefinition.Properties.Add(property); }
void ProcessMethod(MethodDefinition method) { if (method == null) { return; } if (method.IsFinal) { return; } if (method.IsStatic) { return; } if (method.IsVirtual) { return; } if (method.IsPrivate) { return; } method.IsVirtual = true; method.IsNewSlot = true; }
void ProcessMethod(MethodDefinition method) { var asyncAttribute = method.CustomAttributes.FirstOrDefault(_ => _.AttributeType.Name == "AsyncStateMachineAttribute"); if (asyncAttribute == null) { var methodProcessor = new MethodProcessor { ModuleWeaver = this, TypeSystem = ModuleDefinition.TypeSystem, Method = method, }; methodProcessor.InnerProcess(); return; } LogError(string.Format("Could not process '{0}'. async methods are not currently supported. Feel free to submit a pull request if you want this feature.", method.FullName)); //var fullName = method.FullName; //var customAttributeArgument = asyncAttribute.ConstructorArguments.First(); //var typeReference = (TypeReference) customAttributeArgument.Value; //var asyncTypeDefinition = typeReference.Resolve(); //var methodProcessorAsync = new MethodProcessorAsync // { // ModuleWeaver = this, // TypeSystem = ModuleDefinition.TypeSystem, // AsyncTypeReference = asyncTypeDefinition, // OriginalMethod = method // }; //methodProcessorAsync.Process(); }