/// <summary> /// Get the number of values removed on the stack for this instruction. /// </summary> /// <param name="self">The Instruction on which the extension method can be called.</param> /// <param name="method">The method inside which the instruction comes from (needed for StackBehaviour.Varpop).</param> /// <param name="currentstacksize">This method returns this value when stack behaviour is StackBehaviour.PopAll.</param> /// <returns>The number of values removed (pop) from the stack for this instruction.</returns> public static int GetPopCount(this Instruction self, MethodReference method, int currentstacksize = 0) { if (self == null) throw new ArgumentException("self"); if (method == null) throw new ArgumentException("method"); var sbp = self.OpCode.StackBehaviourPop; if (sbp != StackBehaviour.Varpop) return sbp != StackBehaviour.PopAll ? StackBehaviourCache[(int)sbp] : currentstacksize; if (self.OpCode.FlowControl == FlowControl.Return) return method.ReturnType.FullName == "System.Void" ? 0 : 1; var calledMethod = self.Operand as MethodReference; // avoid allocating empty ParameterDefinitionCollection var n = calledMethod.HasParameters ? calledMethod.Parameters.Count : 0; if (self.OpCode.Code == Code.Newobj) return n; if (calledMethod.HasThis) n++; return n; }
public Instruction Create(OpCode opcode, MethodReference meth) { if (opcode.OperandType != OperandType.InlineMethod && opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); return FinalCreate (opcode, meth); }
public GenericContext (IGenericParameterProvider provider) { if (provider is TypeReference) m_type = provider as TypeReference; else if (provider is MethodReference) { MethodReference meth = provider as MethodReference; m_method = meth; m_type = meth.DeclaringType; } }
internal LockReplacer(SourceMethodBody sourceMethodBody) { Contract.Requires(sourceMethodBody != null); this.host = sourceMethodBody.host; Contract.Assume(sourceMethodBody.host != null); this.sourceLocationProvider = sourceMethodBody.sourceLocationProvider; this.numberOfReferencesToLocal = sourceMethodBody.numberOfReferencesToLocal; Contract.Assume(sourceMethodBody.numberOfReferencesToLocal != null); this.numberOfAssignmentsToLocal = sourceMethodBody.numberOfAssignmentsToLocal; Contract.Assume(sourceMethodBody.numberOfAssignmentsToLocal != null); this.bindingsThatMakeALastUseOfALocalVersion = sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion; Contract.Assume(sourceMethodBody.bindingsThatMakeALastUseOfALocalVersion != null); var systemThreading = new Immutable.NestedUnitNamespaceReference(this.host.PlatformType.SystemObject.ContainingUnitNamespace, this.host.NameTable.GetNameFor("Threading")); var systemThreadingMonitor = new Immutable.NamespaceTypeReference(this.host, systemThreading, this.host.NameTable.GetNameFor("Monitor"), 0, isEnum: false, isValueType: false, typeCode: PrimitiveTypeCode.NotPrimitive); var parameters = new IParameterTypeInformation[2]; this.monitorEnter = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid, this.host.NameTable.GetNameFor("Enter"), 0, parameters); parameters[0] = new SimpleParameterTypeInformation(monitorEnter, 0, this.host.PlatformType.SystemObject); parameters[1] = new SimpleParameterTypeInformation(monitorEnter, 1, this.host.PlatformType.SystemBoolean, isByReference: true); this.monitorExit = new MethodReference(this.host, systemThreadingMonitor, CallingConvention.Default, this.host.PlatformType.SystemVoid, this.host.NameTable.GetNameFor("Exit"), 0, this.host.PlatformType.SystemObject); }
private static PropertyDefinition GetMethodDeclaringProperty(MethodReference method) { if (method == null) { return null; } TypeDefinition type = method.DeclaringType.Resolve(); if (type != null) { foreach (PropertyDefinition property in type.Properties) { if ((property.GetMethod != null && property.GetMethod.HasSameSignatureWith(method)) || (property.SetMethod != null && property.SetMethod.HasSameSignatureWith(method))) { return property; } } } return null; }
public static bool HasCopyConstructor(this TypeDefinition type, out MethodReference constructor) { constructor = type.GetConstructors().SingleOrDefault(c => c.HasSingleParameter(type)); return(constructor != null); }
internal MethodRefSignatureConverter(PEFileToObjectModel peFileToObjectModel, MethodReference moduleMethodRef, MemoryReader signatureMemoryReader) : base(peFileToObjectModel, signatureMemoryReader, moduleMethodRef) { // TODO: Check minimum required size of the signature... byte firstByte = this.SignatureMemoryReader.ReadByte(); if (SignatureHeader.IsGeneric(firstByte)) { this.GenericParamCount = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32(); } int paramCount = this.SignatureMemoryReader.ReadCompressedUInt32(); bool dummyPinned; this.ReturnCustomModifiers = this.GetCustomModifiers(out dummyPinned); byte retByte = this.SignatureMemoryReader.PeekByte(0); if (retByte == ElementType.Void) { this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemVoid; this.SignatureMemoryReader.SkipBytes(1); } else if (retByte == ElementType.TypedReference) { this.ReturnTypeReference = peFileToObjectModel.PlatformType.SystemTypedReference; this.SignatureMemoryReader.SkipBytes(1); } else { if (retByte == ElementType.ByReference) { this.IsReturnByReference = true; this.SignatureMemoryReader.SkipBytes(1); } this.ReturnTypeReference = this.GetTypeReference(); } if (paramCount > 0) { this.RequiredParameters = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount); if (this.RequiredParameters.Length < paramCount) this.VarArgParameters = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount - this.RequiredParameters.Length); } }
public Instruction Emit (OpCode opcode, MethodReference meth) { Instruction instr = Create (opcode, meth); Append (instr); return instr; }
public CustomAttrib (MethodReference ctor) { Constructor = ctor; }
public ValueTarget Callvirt(MethodReference method) { _callvirt = method; return(this); }
/// <summary> /// Generates IL for the specified create delegate instance. /// </summary> /// <param name="createDelegateInstance">The create delegate instance.</param> public override void TraverseChildren(ICreateDelegateInstance createDelegateInstance) { IPlatformType platformType = createDelegateInstance.Type.PlatformType; MethodReference constructor = new MethodReference(this.host, createDelegateInstance.Type, CallingConvention.Default|CallingConvention.HasThis, platformType.SystemVoid, this.host.NameTable.Ctor, 0, platformType.SystemObject, platformType.SystemIntPtr); if (createDelegateInstance.Instance != null) { this.Traverse(createDelegateInstance.Instance); if (createDelegateInstance.IsVirtualDelegate) { this.generator.Emit(OperationCode.Dup); this.StackSize++; this.generator.Emit(OperationCode.Ldvirtftn, createDelegateInstance.MethodToCallViaDelegate); this.StackSize--; } else this.generator.Emit(OperationCode.Ldftn, createDelegateInstance.MethodToCallViaDelegate); this.StackSize++; } else { this.generator.Emit(OperationCode.Ldnull); this.generator.Emit(OperationCode.Ldftn, createDelegateInstance.MethodToCallViaDelegate); this.StackSize+=2; } this.generator.Emit(OperationCode.Newobj, constructor); this.StackSize--; }
public static bool IsGenericMethod(MethodReference methodDefinition) { return(methodDefinition.GenericParameters.Count > 0); }
public MethodReference Import(MethodReference meth) { return m_importer.ImportMethodReference (meth, this); }
/// <summary> /// Finds dependencies based on an operand. /// </summary> /// <param name="operand">Operand for instruction</param> /// <returns>Imported operand for target instruction.</returns> protected override IEnumerable <object> InvokeForOperand(MethodReference operand) { Contract.Requires(operand != null); return(operand.GetDependencies()); }
/// <summary> /// Creates a new method for invoking the original test method from the testing engine. /// </summary> internal void RewriteTestMethod(MethodDefinition method, MethodDefinition testMethod) { bool isAsyncMethod = false; TypeReference asyncReturnType = null; // move any AsyncStateMachineAttributes. foreach (var attr in method.CustomAttributes.ToArray()) { var typeName = attr.AttributeType.FullName; if (typeName == "System.Runtime.CompilerServices.AsyncStateMachineAttribute") { isAsyncMethod = true; asyncReturnType = method.ReturnType; method.ReturnType = this.Module.ImportReference(typeof(void)); } if (typeName == "System.Runtime.CompilerServices.AsyncStateMachineAttribute" || typeName == "System.Diagnostics.DebuggerStepThroughAttribute") { method.CustomAttributes.Remove(attr); testMethod.CustomAttributes.Add(attr); } } method.Body.Variables.Clear(); method.Body.Instructions.Clear(); method.Body.ExceptionHandlers.Clear(); MethodReference launchMethod = null; if (this.Configuration.AttachDebugger) { var debuggerType = this.Module.ImportReference(typeof(System.Diagnostics.Debugger)).Resolve(); launchMethod = FindMethod("Launch", debuggerType); } TypeReference actionType; if (isAsyncMethod) { var funcType = this.Module.ImportReference(typeof(Func <>)); actionType = MakeGenericType(funcType, asyncReturnType); } else { actionType = this.Module.ImportReference(typeof(Action)); } var configurationType = this.Module.ImportReference(typeof(Configuration)); var engineType = this.Module.ImportReference(typeof(TestingEngine)); var resolvedActionType = actionType.Resolve(); // Func<> var resolvedConfigurationType = configurationType.Resolve(); var resolvedEngineType = engineType.Resolve(); MethodReference actionConstructor = this.Module.ImportReference( resolvedActionType.Methods.FirstOrDefault(m => m.IsConstructor)); if (isAsyncMethod) { actionConstructor = MakeGenericMethod(actionConstructor, asyncReturnType); } MethodReference createConfigurationMethod = this.Module.ImportReference( resolvedConfigurationType.Methods.FirstOrDefault(m => m.Name is "Create")); MethodReference createEngineMethod = this.Module.ImportReference( FindMethod("Create", resolvedEngineType, configurationType, actionType)); // The emitted IL corresponds to a method body such as: // Configuration configuration = Configuration.Create(); // TestingEngine engine = TestingEngine.Create(configuration, new Action(Test)); // engine.Run(); // engine.ThrowIfBugFound(); // // With optional calls to setup some of the configuration options based on Coyote command line: // including: // configuration.WithTestingIterations(n); // configuration.WithMaxSchedulingSteps(x, y); // configuration.WithProbabilisticStrategy(x); // configuration.WithPCTStrategy(x); // configuration.SchedulingStrategy(x); // configuration.WithLivenessTemperatureThreshold(x); // configuration.WithTimeoutDelay(x); // configuration.WithRandomGeneratorSeed(x); // configuration.WithVerbosityEnabled(x); // configuration.WithTelemetryEnabled(x); var processor = method.Body.GetILProcessor(); if (launchMethod != null) { processor.Emit(OpCodes.Call, this.Module.ImportReference(launchMethod)); processor.Emit(OpCodes.Pop); } var defaultConfig = Configuration.Create(); processor.Emit(OpCodes.Call, createConfigurationMethod); if (this.Configuration.TestingIterations != defaultConfig.TestingIterations) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithTestingIterations", this.Configuration.TestingIterations); } if (this.Configuration.MaxUnfairSchedulingSteps != defaultConfig.MaxUnfairSchedulingSteps || this.Configuration.MaxFairSchedulingSteps != defaultConfig.MaxFairSchedulingSteps) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithMaxSchedulingSteps", (uint)this.Configuration.MaxUnfairSchedulingSteps, (uint)this.Configuration.MaxFairSchedulingSteps); } if (this.Configuration.SchedulingStrategy != defaultConfig.SchedulingStrategy) { switch (this.Configuration.SchedulingStrategy) { case "fairpct": this.EmitMethodCall(processor, resolvedConfigurationType, "WithProbabilisticStrategy", (uint)this.Configuration.StrategyBound); break; case "pct": this.EmitMethodCall(processor, resolvedConfigurationType, "WithPCTStrategy", false, (uint)this.Configuration.StrategyBound); break; case "dfs": this.EmitMethodCall(processor, resolvedConfigurationType, "SchedulingStrategy", this.Configuration.ScheduleTrace); break; default: break; } } if (this.Configuration.UserExplicitlySetLivenessTemperatureThreshold) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithLivenessTemperatureThreshold", (uint)this.Configuration.LivenessTemperatureThreshold); } if (this.Configuration.TimeoutDelay != defaultConfig.TimeoutDelay) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithTimeoutDelay", this.Configuration.TimeoutDelay); } if (this.Configuration.RandomGeneratorSeed.HasValue) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithRandomGeneratorSeed", this.Configuration.RandomGeneratorSeed.Value); } if (this.Configuration.IsVerbose) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithVerbosityEnabled", this.Configuration.IsVerbose, this.Configuration.LogLevel); } if (!this.Configuration.EnableTelemetry) { this.EmitMethodCall(processor, resolvedConfigurationType, "WithTelemetryEnabled", this.Configuration.EnableTelemetry); } processor.Emit(OpCodes.Ldarg_0); processor.Emit(OpCodes.Ldftn, testMethod); processor.Emit(OpCodes.Newobj, actionConstructor); processor.Emit(OpCodes.Call, createEngineMethod); processor.Emit(OpCodes.Dup); this.EmitMethodCall(processor, resolvedEngineType, "Run"); this.EmitMethodCall(processor, resolvedEngineType, "ThrowIfBugFound"); processor.Emit(OpCodes.Ret); method.Body.OptimizeMacros(); }
/// <summary>Try rewriting the direct field reference with reflection access.</summary> /// <param name="cil">The CIL processor.</param> /// <param name="module">The assembly module containing the instruction.</param> /// <param name="instruction">The CIL instruction to rewrite.</param> /// <param name="fieldRef">The field reference.</param> /// <param name="isRead">Whether the field is being read; else it's being written to.</param> /// <param name="isStatic">Whether the field is static field; else it's instance field.</param> /// <param name="declaringType">The type on which the field was defined.</param> private bool TryRewriteWithReflection(ILProcessor cil, ModuleDefinition module, Instruction instruction, FieldReference fieldRef, bool isRead, bool isStatic) { MethodReference getTypeFromHandleRef = module.ImportReference(typeof(Type).GetMethod("GetTypeFromHandle", new Type[] { typeof(RuntimeTypeHandle) })); MethodReference getFieldRef = module.ImportReference(typeof(Type).GetMethod("GetField", new Type[] { typeof(string), typeof(BindingFlags) })); VariableDefinition varInstance = null; if (isRead) { if (!isStatic) { varInstance = new VariableDefinition(fieldRef.DeclaringType); cil.Body.Variables.Add(varInstance); } // inverse order insert // load instance (origin logic, if not static) // stloc.s 0 // ldtoken MonoGame.Framework.Patcher.Test // call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle) // ldstr text // ldc.i4.s 60 // callvirt System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags) // ldloc.0 // callvirt System.Object System.Reflection.FieldInfo::GetValue(System.Object) // castclass System.String if (fieldRef.FieldType.IsValueType) { cil.InsertAfter(instruction, cil.Create(OpCodes.Unbox_Any, fieldRef.FieldType)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Castclass, fieldRef.FieldType)); } MethodReference getValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.GetValue))); cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getValueMethodRef)); if (!isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull)); } cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name)); cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef)); if (!isStatic) { // prohibit replace remove entry point (may cause jump logic broken) cil.InsertAfter(instruction, cil.Create(OpCodes.Nop)); instruction.OpCode = OpCodes.Stloc_S; instruction.Operand = varInstance; instruction = instruction.Next; } } else { VariableDefinition varValue = null; if (!isStatic) { varInstance = new VariableDefinition(fieldRef.DeclaringType); cil.Body.Variables.Add(varInstance); } varValue = new VariableDefinition(fieldRef.FieldType); cil.Body.Variables.Add(varValue); // inverse order insert // load instance (origin logic, if not static) // load value (origin logic) // stloc.s 0 // ldtoken Patcher.TestClass // call System.Type System.Type::GetTypeFromHandle(System.RuntimeTypeHandle) // ldstr text // ldc.i4.s 60 // callvirt System.Reflection.FieldInfo System.Type::GetField(System.String,System.Reflection.BindingFlags) // ldloc.0 // ldloc.1 // callvirt System.Object System.Reflection.FieldInfo::SetValue(System.Object, System.Object) MethodReference setValueMethodRef = module.ImportReference(AccessTools.Method(typeof(FieldInfo), nameof(FieldInfo.SetValue), new Type[] { typeof(object), typeof(object) })); cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, setValueMethodRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varValue)); if (isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldnull)); } else { cil.InsertAfter(instruction, cil.Create(OpCodes.Ldloc_S, varInstance)); } cil.InsertAfter(instruction, cil.Create(OpCodes.Callvirt, getFieldRef)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldc_I4_S, (sbyte)60)); cil.InsertAfter(instruction, cil.Create(OpCodes.Ldstr, fieldRef.Name)); cil.InsertAfter(instruction, cil.Create(OpCodes.Call, getTypeFromHandleRef)); // prohibit replace remove entry point (may cause jump logic broken) instruction.OpCode = OpCodes.Stloc_S; instruction.Operand = varValue; cil.InsertAfter(instruction, cil.Create(OpCodes.Nop)); if (!isStatic) { cil.InsertAfter(instruction, cil.Create(OpCodes.Stloc_S, varInstance)); instruction = instruction.Next; } instruction = instruction.Next; } // rewrite field ref to ldtoken instruction.OpCode = OpCodes.Ldtoken; instruction.Operand = fieldRef.DeclaringType; this.Phrases.Add($"{fieldRef.DeclaringType.Name}.{fieldRef.Name} (field ref => reflection ref)"); // #if SMAPI_FOR_MOBILE // this.Phrases.Add($"{cil.Body.Method.FullName} => {cil.Body.Instructions.Select(ins => ins.ToString()).Join(null, ";")}"); // #endif cil.Body.MaxStackSize += 5; return(this.MarkRewritten()); }
private static void InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(CecilContext stardewContext, ILProcessor ilProcessor, IEnumerable <Instruction> targets, MethodReference method, bool isExit = false) { foreach (var target in targets.ToList()) { InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(stardewContext, ilProcessor, target, method, isExit); } }
protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action <ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode) { if (methodInfo.IsAbstract) { CecilExtensions.CreateDefaultMethodImplementation(methodInfo, il); } else { base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode); } }
public static bool IsGenericMethod(this MethodReference method) { return(method.GenericParameters.Count > 0); }
public override void WriteTo(ITextOutput output) { if (Operand is ILVariable && ((ILVariable)Operand).IsGenerated) { if (Code == ILCode.Stloc && this.InferredType == null) { output.Write(((ILVariable)Operand).Name); output.Write(" = "); Arguments.First().WriteTo(output); return; } else if (Code == ILCode.Ldloc) { output.Write(((ILVariable)Operand).Name); if (this.InferredType != null) { output.Write(':'); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } return; } } if (this.Prefixes != null) { foreach (var prefix in this.Prefixes) { output.Write(prefix.Code.GetName()); output.Write(". "); } } output.Write(Code.GetName()); if (this.InferredType != null) { output.Write(':'); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } else if (this.ExpectedType != null) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } output.Write('('); bool first = true; if (Operand != null) { if (Operand is ILLabel) { output.WriteReference(((ILLabel)Operand).Name, Operand); } else if (Operand is ILLabel[]) { ILLabel[] labels = (ILLabel[])Operand; for (int i = 0; i < labels.Length; i++) { if (i > 0) { output.Write(", "); } output.WriteReference(labels[i].Name, labels[i]); } } else if (Operand is MethodReference) { MethodReference method = (MethodReference)Operand; if (method.DeclaringType != null) { method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); } output.WriteReference(method.Name, method); } else if (Operand is FieldReference) { FieldReference field = (FieldReference)Operand; field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); output.WriteReference(field.Name, field); } else { DisassemblerHelpers.WriteOperand(output, Operand); } first = false; } foreach (ILExpression arg in this.Arguments) { if (!first) { output.Write(", "); } arg.WriteTo(output); first = false; } output.Write(')'); }
public GenericContext(TypeReference type, MethodReference meth) { m_type = type; m_method = meth; }
public void Execute() { var markerDll = Check(() => ModuleDefinition.AssemblyReferences.SingleOrDefault(a => a.Name.ToLowerInvariant() == "AutoDependencyPropertyMarker".ToLowerInvariant()), "find AutoDependencyPropertyMarker reference"); if (markerDll == null) { return; } var windowsBase = CheckAssembly("WindowsBase", description: "Couldn't find reference to WindowsBase. Or it isn't referenced by project or it was stripped because it wasn't referenced from code. Make sure that your types are subtypes of DependencyObject."); 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); }
//^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null; internal MemberReference/*?*/ GetModuleMemberReferenceAtRowWorker( MetadataObject owningObject, uint memberRefRowId ) { if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) { return null; } if (this.ModuleMemberReferenceArray[memberRefRowId] == null) { MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId]; uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask; uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask; IModuleTypeReference/*?*/ parentTypeReference = null; switch (classTokenType) { case TokenTypeIds.TypeDef: parentTypeReference = this.GetTypeDefinitionAtRowWorker(classRowId); break; case TokenTypeIds.TypeRef: parentTypeReference = this.GetTypeRefReferenceAtRowWorker(classRowId); break; case TokenTypeIds.TypeSpec: parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference; break; case TokenTypeIds.MethodDef: { MethodDefinition/*?*/ methodDef = this.GetMethodDefAtRow(classRowId); if (methodDef == null) { // Error... return null; } parentTypeReference = methodDef.OwningModuleType; break; } case TokenTypeIds.ModuleRef: { ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId); if (modRef == null) { // MDError return null; } Module/*?*/ module = this.ResolveModuleRefReference(modRef); if (module == null) { //TODO: MDError... return null; } PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel; parentTypeReference = modulePEFileToObjectModel._Module_; break; } default: { // MDError... return null; } } if (parentTypeReference == null) { // Error... return null; } MemberReference retModuleMemberReference; IName name = this.GetNameFromOffset(memberRefRow.Name); byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0); IModuleGenericTypeInstance/*?*/ genericTypeInstance = parentTypeReference as IModuleGenericTypeInstance; IModuleSpecializedNestedTypeReference/*?*/ specializedNestedTypeReference = parentTypeReference as IModuleSpecializedNestedTypeReference; if (SignatureHeader.IsFieldSignature(firstByte)) { if (genericTypeInstance != null) { //The same memberRef token can be shared by distinct instance references, therefore recompute every time. return new GenericInstanceFieldReference(this, memberRefRowId, genericTypeInstance, name); } else if (specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore recompute every time. return new SpecializedNestedTypeFieldReference(this, memberRefRowId, parentTypeReference, specializedNestedTypeReference, name); } else { retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name); } } else if (SignatureHeader.IsMethodSignature(firstByte)) { if (genericTypeInstance != null) { //The same memberRef token can be shared by distinct instance references, therefore recompute every time. return new GenericInstanceMethodReference(this, memberRefRowId, genericTypeInstance, name, firstByte); } else if (specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore recompute every time. return new SpecializedNestedTypeMethodReference(this, memberRefRowId, parentTypeReference, specializedNestedTypeReference, name, firstByte); } else { retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte); } } else { // MD Error return null; } this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference; } MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId]; return ret; }
private IEnumerable <AssemblyLine> Call(Instruction instruction) { // Could be either a MethodDefinition or MethodReference. MethodReference method = (MethodReference)instruction.Operand; var methodDeclaringType = method.DeclaringType.FullName; var processedSubroutine = Types[methodDeclaringType].Subroutines.Single(s => s.FullName == method.FullName); // Check if this method should be replaced with a direct store to a symbol (generally a TIA register). // Don't directly compare types since we may have received a different Framework assembly than what this library was built against. if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithStoreToSymbolAttribute>(out var overrideStore)) { if (!overrideStore.Strobe) { //TODO - We assume this is a 1-arg void method. Actually enforce this at the processing stage. if (method.Parameters.Count != 1) { throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithStoreToSymbolAttribute)}, must take 1 parameter for now."); } yield return(PLA()); } yield return(STA(overrideStore.Symbol)); yield break; } if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithLoadToRegisterAttribute>(out var overrideRegisterLoad)) { //TODO - We assume this is a 1-arg void method. Actually enforce this at the processing stage. if (method.Parameters.Count != 1) { throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithLoadToRegisterAttribute)} must take 1 parameter."); } yield return(PLA()); switch (overrideRegisterLoad.Register) { case "A": break; case "X": yield return(TAX()); break; case "Y": yield return(TAY()); break; default: throw new FatalCompilationException($"Attempted load to unknown register: {overrideRegisterLoad.Register}"); } yield break; } if (processedSubroutine.TryGetFrameworkAttribute <OverrideWithLoadFromSymbolAttribute>(out var overrideLoad)) { if (method.Parameters.Count != 0) { throw new NotImplementedException($"{method.Name}, marked with {nameof(OverrideWithLoadFromSymbolAttribute)}, must take 0 parameters."); } yield return(LDA(overrideLoad.Symbol)); yield return(PHA()); yield break; } var parameters = ((MethodReference)method).Parameters.ToImmutableArray(); if (parameters.Any()) { // PLA arguments in reverse off stack and assign to parameters. foreach (var parameter in parameters.Reverse()) { yield return(PLA()); yield return(STA(LabelGenerator.GetFromParameter(parameter))); } } if (processedSubroutine.TryGetFrameworkAttribute <AlwaysInlineAttribute>(out _)) { var compiledSubroutine = Types[method.DeclaringType.FullName].Subroutines.Single(s => s.FullName == method.FullName) as CompiledSubroutine; if (compiledSubroutine == null) { throw new FatalCompilationException($"Attempted to inline method '{processedSubroutine.Name}' that hasn't been compiled yet. This suggests a bug in determining method compilation order."); } foreach (var assemblyLine in compiledSubroutine.Body) { //TODO - If the subroutine contains labels you can end up emitting duplicates if the inline subroutine is called more than once. Make them unique. //TODO - Once we have branching and multiple return statements this will explode. // In reality we probably want to replace RTS with JMP to a label inserted after this method body. if (!assemblyLine.Text.Contains("RTS")) { yield return(assemblyLine); } } yield break; } yield return(JSR(LabelGenerator.GetFromMethod(method))); }
internal MethodRefSignatureConverter GetMethodRefSignature( MethodReference moduleMethodReference ) { uint signatureBlobOffset = this.PEFileReader.MemberRefTable.GetSignature(moduleMethodReference.MemberRefRowId); // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); // TODO: Check if this is really method signature there. MethodRefSignatureConverter methodRefSigConv = new MethodRefSignatureConverter(this, moduleMethodReference, memoryReader); return methodRefSigConv; }
/// <summary /> public override IStatement Rewrite(IForEachStatement forEachStatement) { ILocalDefinition foreachLocal; var key = forEachStatement.Collection.Type.InternedKey; ITypeReference enumeratorType; IMethodReference getEnumerator; IMethodReference getCurrent; var gtir = forEachStatement.Collection.Type as IGenericTypeInstanceReference; if (gtir != null) { var typeArguments = gtir.GenericArguments; ITypeReference genericEnumeratorType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerator, typeArguments, this.host.InternFactory); ITypeReference genericEnumerableType = new Immutable.GenericTypeInstanceReference(this.host.PlatformType.SystemCollectionsGenericIEnumerable, typeArguments, this.host.InternFactory); enumeratorType = genericEnumeratorType; getEnumerator = new SpecializedMethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = genericEnumerableType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = genericEnumeratorType, UnspecializedVersion = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = this.host.PlatformType.SystemCollectionsGenericIEnumerable, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsGenericIEnumerator, }, }; var getEnumerator2 = (IMethodReference) IteratorHelper.First(genericEnumerableType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("GetEnumerator"), false)); getEnumerator = getEnumerator2; getCurrent = (IMethodReference) IteratorHelper.First(genericEnumeratorType.ResolvedType.GetMembersNamed(this.host.NameTable.GetNameFor("get_Current"), false)); } else { enumeratorType = this.host.PlatformType.SystemCollectionsIEnumerator; getEnumerator = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("GetEnumerator"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemCollectionsIEnumerable, }; getCurrent = new MethodReference() { CallingConvention = CallingConvention.HasThis, ContainingType = enumeratorType, InternFactory = this.host.InternFactory, Name = this.host.NameTable.GetNameFor("get_Current"), Parameters = new List<IParameterTypeInformation>(), Type = this.host.PlatformType.SystemObject, }; } var initializer = new MethodCall() { Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getEnumerator, ThisArgument = forEachStatement.Collection, Type = enumeratorType, }; IStatement initialization; if (!this.foreachLocals.TryGetValue(key, out foreachLocal)) { foreachLocal = new LocalDefinition() { Type = enumeratorType, Name = this.host.NameTable.GetNameFor("CS$5$" + this.foreachLocals.Count) }; this.foreachLocals.Add(key, foreachLocal); initialization = new LocalDeclarationStatement() { InitialValue = initializer, LocalVariable = foreachLocal, }; } else { initialization = new ExpressionStatement() { Expression = new Assignment() { Source = initializer, Target = new TargetExpression() { Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, Type = foreachLocal.Type, }, }; } var newStmts = new List<IStatement>(); newStmts.Add(new ExpressionStatement(){ Expression = new Assignment(){ Source = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = getCurrent, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = forEachStatement.Variable.Type, }, Target = new TargetExpression(){ Definition = forEachStatement.Variable, Instance = null, }, Type = forEachStatement.Variable.Type, }, }); newStmts.Add(forEachStatement.Body); var newBody = new BlockStatement(){ Statements = newStmts,}; var result = new BlockStatement() { Statements = new List<IStatement>(){ initialization, new TryCatchFinallyStatement(){ TryBody = new BlockStatement() { Statements = new List<IStatement>(){ new WhileDoStatement(){ Body = newBody, Condition = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = moveNext, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemBoolean, }, }, }, }, FinallyBody = new BlockStatement() { Statements = new List<IStatement>(){ new ConditionalStatement(){ Condition = new Equality(){ LeftOperand = new BoundExpression(){ Definition = foreachLocal, Instance = null, Type = foreachLocal.Type, }, RightOperand = new CompileTimeConstant(){ Type = foreachLocal.Type, Value = null, }, Type = this.host.PlatformType.SystemBoolean, }, FalseBranch = new EmptyStatement(), TrueBranch = new ExpressionStatement(){ Expression = new MethodCall(){ Arguments = new List<IExpression>(), IsStaticCall = false, IsVirtualCall = true, MethodToCall = this.disposeMethod, ThisArgument = new BoundExpression(){ Definition = foreachLocal, Instance = null, }, Type = this.host.PlatformType.SystemVoid, }, }, }, }, }, }, }, }; return result; }
public Instruction Create(OpCode opcode, MethodReference method) { return Instruction.Create (opcode, method); }
public RuleResult CheckMethod(MethodDefinition method) { // rule apply only if the method has a body (e.g. p/invokes, icalls don't) if (!method.HasBody || method.IsGeneratedCode()) { return(RuleResult.DoesNotApply); } // is there any Call or Callvirt instructions in the method OpCodeBitmask bitmask = OpCodeEngine.GetBitmask(method); if (!OpCodeBitmask.Calls.Intersect(bitmask)) { return(RuleResult.DoesNotApply); } foreach (Instruction ins in method.Body.Instructions) { Code code = ins.OpCode.Code; if ((code != Code.Call) && (code != Code.Callvirt)) { continue; } MethodReference mref = (ins.Operand as MethodReference); // covers Equals(string) method and both == != operators switch (mref.Name) { case "Equals": if (mref.Parameters.Count > 1) { continue; } TypeReference type = mref.DeclaringType; if (type.Namespace != "System") { continue; } string name = type.Name; if ((name != "String") && (name != "Object")) { continue; } break; case "op_Equality": case "op_Inequality": if (!mref.DeclaringType.IsNamed("System", "String")) { continue; } break; default: continue; } Instruction prev = ins.Previous; switch (prev.OpCode.Code) { case Code.Ldstr: if ((prev.Operand as string).Length > 0) { continue; } break; case Code.Ldsfld: FieldReference field = (prev.Operand as FieldReference); if (!field.DeclaringType.IsNamed("System", "String")) { continue; } // unlikely to be anything else (at least with released fx) if (field.Name != "Empty") { continue; } break; default: continue; } Runner.Report(method, ins, Severity.Medium, Confidence.High); } return(Runner.CurrentRuleResult); }
public static Instruction Create (OpCode opcode, MethodReference method) { if (method == null) throw new ArgumentNullException ("method"); if (opcode.OperandType != OperandType.InlineMethod && opcode.OperandType != OperandType.InlineTok) throw new ArgumentException ("opcode"); return new Instruction (opcode, method); }
/// <summary>Get whether a type has a method whose signature matches the one expected by a method reference.</summary> /// <param name="type">The type to check.</param> /// <param name="reference">The method reference.</param> public static bool HasMatchingSignature(Type type, MethodReference reference) { return(type .GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public) .Any(method => RewriteHelper.HasMatchingSignature(method, reference))); }
void IntroducePropertyAccessInstructions(ILExpression expr, ILExpression parentExpr, int posInParent) { if (expr.Code == ILCode.Call || expr.Code == ILCode.Callvirt) { MethodReference cecilMethod = (MethodReference)expr.Operand; if (cecilMethod.DeclaringType is ArrayType) { switch (cecilMethod.Name) { case "Get": expr.Code = ILCode.CallGetter; break; case "Set": expr.Code = ILCode.CallSetter; break; case "Address": ByReferenceType brt = cecilMethod.ReturnType as ByReferenceType; if (brt != null) { MethodReference getMethod = new MethodReference("Get", brt.ElementType, cecilMethod.DeclaringType); foreach (var p in cecilMethod.Parameters) { getMethod.Parameters.Add(p); } getMethod.HasThis = cecilMethod.HasThis; expr.Operand = getMethod; } expr.Code = ILCode.CallGetter; if (parentExpr != null) { parentExpr.Arguments[posInParent] = new ILExpression(ILCode.AddressOf, null, expr); } break; } } else { MethodDefinition cecilMethodDef = cecilMethod.Resolve(); if (cecilMethodDef != null) { if (cecilMethodDef.IsGetter) { expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallGetter : ILCode.CallvirtGetter; } else if (cecilMethodDef.IsSetter) { expr.Code = (expr.Code == ILCode.Call) ? ILCode.CallSetter : ILCode.CallvirtSetter; } } } } else if (expr.Code == ILCode.Newobj && expr.Arguments.Count == 2) { // Might be 'newobj(SomeDelegate, target, ldvirtftn(F, target))'. ILVariable target; if (expr.Arguments[0].Match(ILCode.Ldloc, out target) && expr.Arguments[1].Code == ILCode.Ldvirtftn && expr.Arguments[1].Arguments.Count == 1 && expr.Arguments[1].Arguments[0].MatchLdloc(target)) { // Remove the 'target' argument from the ldvirtftn instruction. // It's not needed in the translation to C#, and needs to be eliminated so that the target expression // can be inlined. expr.Arguments[1].Arguments.Clear(); } } }
void GenerateSerialization() { Weaver.DLog(m_td, " GenerateSerialization"); foreach (var m in m_td.Methods) { if (m.Name == "Serialize") { return; } } if (m_td.Fields.Count == 0) { return; } // check for self-referencing types foreach (var field in m_td.Fields) { if (field.FieldType.FullName == m_td.FullName) { Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FullName + "]. [MessageBase] member cannot be self referencing."); return; } } MethodDefinition serializeFunc = new MethodDefinition("Serialize", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, Weaver.voidType); serializeFunc.Parameters.Add(new ParameterDefinition("writer", ParameterAttributes.None, Weaver.scriptDef.MainModule.ImportReference(Weaver.NetworkWriterType))); ILProcessor serWorker = serializeFunc.Body.GetILProcessor(); foreach (var field in m_td.Fields) { if (field.IsStatic || field.IsPrivate || field.IsSpecialName) { continue; } if (field.FieldType.Resolve().HasGenericParameters) { Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot have generic parameters."); return; } if (field.FieldType.Resolve().IsInterface) { Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member cannot be an interface."); return; } MethodReference writeFunc = Weaver.GetWriteFunc(field.FieldType); if (writeFunc != null) { serWorker.Append(serWorker.Create(OpCodes.Ldarg_1)); serWorker.Append(serWorker.Create(OpCodes.Ldarg_0)); serWorker.Append(serWorker.Create(OpCodes.Ldfld, field)); serWorker.Append(serWorker.Create(OpCodes.Call, writeFunc)); } else { Weaver.fail = true; Log.Error("GenerateSerialization for " + m_td.Name + " unknown type [" + field.FieldType + "/" + field.FieldType.FullName + "]. [MessageBase] member variables must be basic types."); return; } } serWorker.Append(serWorker.Create(OpCodes.Ret)); m_td.Methods.Add(serializeFunc); }
private static void InjectMethod <TParam, TThis, TInput, TLocal>(CecilContext stardewContext, ILProcessor ilProcessor, Instruction target, MethodReference method, bool isExit = false, bool cancelable = false) { ilProcessor.Body.SimplifyMacros(); var callEnterInstruction = ilProcessor.Create(OpCodes.Call, method); if (method.HasThis) { var loadObjInstruction = ilProcessor.Create(OpCodes.Ldarg_0); ilProcessor.InsertBefore(target, loadObjInstruction); } if (method.HasParameters) { Instruction prevInstruction = null; var paramLdInstruction = target; var first = true; foreach (var parameter in method.Parameters) { paramLdInstruction = GetInstructionForParameter <TParam, TThis, TInput, TLocal, Patcher, Patcher>(stardewContext, ilProcessor, parameter); if (paramLdInstruction == null) { throw new Exception($"Error parsing parameter setup on {parameter.Name}"); } if (isExit) { if (first) { first = false; ilProcessor.Replace(target, paramLdInstruction); } else { ilProcessor.InsertAfter(prevInstruction, paramLdInstruction); } prevInstruction = paramLdInstruction; } else { ilProcessor.InsertBefore(target, paramLdInstruction); } } if (isExit) { if (first) { ilProcessor.Replace(target, callEnterInstruction); ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret)); } else { ilProcessor.InsertAfter(prevInstruction, callEnterInstruction); ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret)); } } else { ilProcessor.InsertAfter(paramLdInstruction, callEnterInstruction); } } else { if (isExit) { ilProcessor.Replace(target, callEnterInstruction); ilProcessor.InsertAfter(callEnterInstruction, ilProcessor.Create(OpCodes.Ret)); } else { ilProcessor.InsertBefore(target, callEnterInstruction); } } if (cancelable) { var branch = ilProcessor.Create(OpCodes.Brtrue, ilProcessor.Body.Instructions.Last()); ilProcessor.InsertAfter(callEnterInstruction, branch); } ilProcessor.Body.OptimizeMacros(); }
public static bool HasSameSignatureWith(this MethodReference self, MethodReference other) { if (!(self.GetMethodSignature() == other.GetMethodSignature())) { return false; } if (self.ReturnType.FullName != other.ReturnType.FullName) { if (self.ReturnType is GenericParameter && other.ReturnType is GenericParameter) { if ((self.ReturnType as GenericParameter).Position == (other.ReturnType as GenericParameter).Position) { return true; } } return false; } return true; }
private static void InjectReturnableMethod <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(CecilContext stardewContext, ILProcessor ilProcessor, Instruction target, MethodReference method, bool isExit = false) { ilProcessor.Body.SimplifyMacros(); // Add UseReturnVal variable if (ilProcessor.Body.Variables.All(n => n.Name != "UseReturnVal")) { var boolType = stardewContext.GetTypeReference(typeof(bool)); ilProcessor.Body.Variables.Add(new VariableDefinition("UseReturnVal", boolType)); } var useOutputVariable = ilProcessor.Body.Variables.First(n => n.Name == "UseReturnVal"); if (ilProcessor.Body.Variables.All(n => n.Name != "ReturnContainer-" + method.ReturnType.Name)) { ilProcessor.Body.Variables.Add(new VariableDefinition("ReturnContainer-" + method.ReturnType.Name, method.ReturnType)); } if (isExit) { if (ilProcessor.Body.Variables.All(n => n.Name != "OldReturnContainer")) { ilProcessor.Body.Variables.Add(new VariableDefinition("OldReturnContainer", method.ReturnType)); } } var containerVariable = ilProcessor.Body.Variables.First(n => n.Name == "ReturnContainer-" + method.ReturnType.Name); var oldContainerVariable = ilProcessor.Body.Variables.FirstOrDefault(n => n.Name == "OldReturnContainer"); List <Instruction> instructions = new List <Instruction>(); if (isExit) { instructions.Add(ilProcessor.Create(OpCodes.Stloc, oldContainerVariable)); } if (method.HasParameters) { foreach (var parameter in method.Parameters) { var paramLdInstruction = GetInstructionForParameter <TParam, TThis, TInput, TLocal, TUseOutput, TMethodOutputBind>(stardewContext, ilProcessor, parameter); if (paramLdInstruction == null) { throw new Exception($"Error parsing parameter setup on {parameter.Name}"); } instructions.Add(paramLdInstruction); } } instructions.Add(ilProcessor.Create(OpCodes.Call, method)); instructions.Add(ilProcessor.Create(OpCodes.Stloc, containerVariable)); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, useOutputVariable)); if (!isExit) { instructions.Add(ilProcessor.Create(OpCodes.Brfalse, target)); instructions.Add(ilProcessor.Create(OpCodes.Ldloc, containerVariable)); instructions.Add(ilProcessor.Create(OpCodes.Br, ilProcessor.Body.Instructions.Last())); } else { var brToRet = ilProcessor.Create(OpCodes.Br, target); var loadOld = ilProcessor.Create(OpCodes.Ldloc, oldContainerVariable); var loadNew = ilProcessor.Create(OpCodes.Ldloc, containerVariable); instructions.Add(ilProcessor.Create(OpCodes.Brfalse, loadOld)); instructions.Add(loadNew); instructions.Add(brToRet); instructions.Add(loadOld); } foreach (var inst in instructions) { ilProcessor.InsertBefore(target, inst); } ilProcessor.Body.OptimizeMacros(); }
public static TypeReference ResolveParameterType(this ParameterReference param, MethodReference method) { TypeReference parameterType = param.ParameterType; GenericParameter genericParameter = parameterType as GenericParameter; //if (parameterType is GenericInstanceType) //{ // return ResolveParameterGenericInstanceType(parameterType as GenericInstanceType); //} bool isByRef = false; bool isArray = false; if (parameterType.IsByReference) { genericParameter = parameterType.GetElementType() as GenericParameter; isByRef = true; } if (parameterType.IsArray) { genericParameter = parameterType.GetElementType() as GenericParameter; isArray = true; } if (genericParameter == null) { return parameterType; } int index = genericParameter.Position; if (genericParameter.Owner is MethodReference && method.IsGenericInstance) { GenericInstanceMethod generic = method as GenericInstanceMethod; if (index >= 0 && index < generic.GenericArguments.Count) { parameterType = generic.GenericArguments[index]; if (generic.PostionToArgument.ContainsKey(index)) { parameterType = generic.PostionToArgument[index]; } } } else if (genericParameter.Owner is TypeReference && method.DeclaringType.IsGenericInstance) { GenericInstanceType generic = method.DeclaringType as GenericInstanceType; if (index >= 0 && index < generic.GenericArguments.Count) { parameterType = generic.GenericArguments[index]; if (generic.PostionToArgument.ContainsKey(index)) { parameterType = generic.PostionToArgument[index]; } } } if (isByRef) { return new ByReferenceType(parameterType); } if (isArray) { return new ArrayType(parameterType); } return parameterType; }
/// <summary> /// Emits the IL that calculates a hash code from a given service type. /// </summary> /// <param name="module">The module that holds the target type.</param> /// <param name="body">The body of the GetServiceHashCode method.</param> /// <param name="il">The <see cref="ILProcessor"/> that will be used to emit the instructions.</param> /// <param name="getHashCodeMethod">The <see cref="Object.GetHashCode"/> method.</param> /// <returns>The variable that holds the hash code.</returns> private static VariableDefinition EmitGetServiceTypeHashCode(ModuleDefinition module, Mono.Cecil.Cil.MethodBody body, ILProcessor il, MethodReference getHashCodeMethod) { // Get the hash code for the service type var hashVariable = AddLocals(module, body); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, getHashCodeMethod); il.Emit(OpCodes.Stloc, hashVariable); return(hashVariable); }
public Instruction Emit(OpCode opcode, MethodReference method) { var instruction = Create (opcode, method); Append (instruction); return instruction; }
private static EventDefinition GetMethodDeclaringEvent(MethodReference method) { if (method == null) { return null; } TypeDefinition type = method.DeclaringType.Resolve(); if (type != null) { foreach (EventDefinition @event in type.Events) { if ((@event.AddMethod != null && @event.AddMethod.HasSameSignatureWith(method)) || (@event.RemoveMethod != null && @event.RemoveMethod.HasSameSignatureWith(method))) { return @event; } } } return null; }
/// <summary> /// Rewrites the declaring <see cref="TypeReference"/> of the specified <see cref="MethodReference"/>. /// </summary> /// <param name="method">The method with the declaring type to rewrite.</param> /// <returns>The rewritten declaring type, or the original if it was not changed.</returns> protected virtual TypeReference RewriteDeclaringTypeReference(MethodReference method) => method.DeclaringType;
public MethodReference ImportMethodReference(MethodReference method, ImportContext context) { return method; }
/// <summary> /// Rewrites the specified <see cref="MethodReference"/>. /// </summary> /// <param name="method">The method reference to rewrite.</param> /// <param name="module">The module definition that is being visited.</param> /// <returns>The rewritten method, or the original if it was not changed.</returns> protected MethodReference RewriteMethodReference(MethodReference method, ModuleDefinition module) { MethodReference result = method; TypeReference declaringType = this.RewriteDeclaringTypeReference(method); if (method.DeclaringType == declaringType) { // We are not rewriting this method. return(result); } MethodDefinition resolvedMethod = Resolve(method); TypeDefinition resolvedDeclaringType = Resolve(declaringType); // This is an extra initial parameter that we have when converting an instance to a static method. // For example, `task.GetAwaiter()` is converted to `ControlledTask.GetAwaiter(task)`. ParameterDefinition instanceParameter = null; MethodDefinition match = FindMatchingMethodInDeclaringType(resolvedMethod, resolvedDeclaringType); if (match != null) { result = module.ImportReference(match); if (resolvedMethod.Parameters.Count != match.Parameters.Count) { // We are converting from an instance method to a static method, so store the instance parameter. instanceParameter = result.Parameters[0]; } } TypeReference returnType = this.RewriteTypeReference(method.ReturnType); // Instantiate the method reference to set its generic arguments and parameters, if any. result = new MethodReference(result.Name, returnType, declaringType) { HasThis = result.HasThis, ExplicitThis = result.ExplicitThis, CallingConvention = result.CallingConvention }; if (resolvedMethod.HasGenericParameters) { // We need to instantiate the generic method. GenericInstanceMethod genericMethodInstance = new GenericInstanceMethod(result); var genericArgs = new List <TypeReference>(); int genericArgOffset = 0; if (declaringType is GenericInstanceType genericDeclaringType) { // Populate the generic arguments with the generic declaring type arguments. genericArgs.AddRange(genericDeclaringType.GenericArguments); genericArgOffset = genericDeclaringType.GenericArguments.Count; } if (method is GenericInstanceMethod genericInstanceMethod) { // Populate the generic arguments with the generic instance method arguments. genericArgs.AddRange(genericInstanceMethod.GenericArguments); } for (int i = 0; i < resolvedMethod.GenericParameters.Count; i++) { var p = resolvedMethod.GenericParameters[i]; var j = p.Position + genericArgOffset; if (j > genericArgs.Count) { throw new InvalidOperationException(string.Format("Not enough generic arguments to instantiate method {0}", method)); } GenericParameter parameter = new GenericParameter(p.Name, genericMethodInstance); result.GenericParameters.Add(parameter); genericMethodInstance.GenericParameters.Add(parameter); genericMethodInstance.GenericArguments.Add(this.RewriteTypeReference(genericArgs[j])); } result = genericMethodInstance; } // Set the instance parameter of the method, if any. if (instanceParameter != null) { result.Parameters.Add(instanceParameter); } // Set the remaining parameters of the method, if any. foreach (var parameter in method.Parameters) { result.Parameters.Add(this.RewriteParameterDefinition(parameter)); } return(module.ImportReference(result)); }
private void ReadMethodReferences(BinaryReader reader) { reader.PreserveCurrentPosition(header.MethodReferencesOffset, () => { for (int i = 0; i < header.MethodReferencesSize; i++) { int classIndex = reader.ReadUInt16(); int prototypeIndex = reader.ReadUInt16(); int nameIndex = reader.ReadInt32(); var mref = new MethodReference(); mref.Owner = (CompositeType) typeReferences[classIndex]; // Clone the prototype so we can annotate & update it easily mref.Prototype = prototypes[prototypeIndex].Clone(); mref.Name = strings[nameIndex]; methodReferences.Add(mref); } }); }
public MethodReference ImportReference(MethodReference methRef) { return(ModelTypeDef.Module.ImportReference(methRef)); }
public MethodReference Import(MethodReference meth) { return m_helper == null ? meth : m_helper.ImportMethodReference (meth, this); }
public MethodReference ImportReference(MethodReference methRef, IGenericParameterProvider context) { return(ModelTypeDef.Module.ImportReference(methRef, context)); }
//^ [NotDelayed] internal MethodRefSignatureConverter( PEFileToObjectModel peFileToObjectModel, MethodReference moduleMethodRef, MemoryReader signatureMemoryReader ) : base(peFileToObjectModel, signatureMemoryReader, moduleMethodRef) { //^ this.ReturnCustomModifiers = TypeCache.EmptyCustomModifierArray; this.RequiredParameters = TypeCache.EmptyParameterInfoArray; this.VarArgParameters = TypeCache.EmptyParameterInfoArray; //^ base; //^ this.SignatureMemoryReader = signatureMemoryReader; //TODO: Spec# bug. This assignment should not be necessary. // TODO: Check minimum required size of the signature... byte firstByte = this.SignatureMemoryReader.ReadByte(); if (SignatureHeader.IsGeneric(firstByte)) { this.GenericParamCount = (ushort)this.SignatureMemoryReader.ReadCompressedUInt32(); } int paramCount = this.SignatureMemoryReader.ReadCompressedUInt32(); bool dummyPinned; this.ReturnCustomModifiers = this.GetCustomModifiers(out dummyPinned); byte retByte = this.SignatureMemoryReader.PeekByte(0); if (retByte == ElementType.Void) { this.ReturnTypeReference = peFileToObjectModel.SystemVoid; this.SignatureMemoryReader.SkipBytes(1); } else if (retByte == ElementType.TypedReference) { this.ReturnTypeReference = peFileToObjectModel.SystemTypedReference; this.SignatureMemoryReader.SkipBytes(1); } else { if (retByte == ElementType.ByReference) { this.IsReturnByReference = true; this.SignatureMemoryReader.SkipBytes(1); } this.ReturnTypeReference = this.GetTypeReference(); } if (paramCount > 0) { IModuleParameterTypeInformation[] reqModuleParamArr = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount); if (reqModuleParamArr.Length > 0) this.RequiredParameters = new EnumerableArrayWrapper<IModuleParameterTypeInformation, IParameterTypeInformation>(reqModuleParamArr, Dummy.ParameterTypeInformation); IModuleParameterTypeInformation[] varArgModuleParamArr = this.GetModuleParameterTypeInformations(moduleMethodRef, paramCount - reqModuleParamArr.Length); if (varArgModuleParamArr.Length > 0) this.VarArgParameters = new EnumerableArrayWrapper<IModuleParameterTypeInformation, IParameterTypeInformation>(varArgModuleParamArr, Dummy.ParameterTypeInformation); } }
/// <summary> /// Gets the index of a method in the corresponding VTable. /// </summary> /// <param name="type">The type.</param> /// <param name="method">The method.</param> /// <returns>The index inside the table of the type.</returns> public int GetMethodIndex(TypeDefinition type, MethodReference method) { string name = NameHelper.CreateShortMethodName(method); return(mNameTable[type][name]); }
//^ invariant this.PEFileReader.MethodSpecTable.NumberOfRows >= 1 ==> this.MethodSpecHashtable != null; internal ITypeMemberReference/*?*/ GetModuleMemberReferenceAtRowWorker( MetadataObject owningObject, uint memberRefRowId ) { if (memberRefRowId == 0 || memberRefRowId > this.PEFileReader.MemberRefTable.NumberOfRows) { return null; } if (this.ModuleMemberReferenceArray[memberRefRowId] == null) { MemberRefRow memberRefRow = this.PEFileReader.MemberRefTable[memberRefRowId]; uint classTokenType = memberRefRow.Class & TokenTypeIds.TokenTypeMask; uint classRowId = memberRefRow.Class & TokenTypeIds.RIDMask; ITypeReference/*?*/ parentTypeReference = null; switch (classTokenType) { case TokenTypeIds.TypeDef: parentTypeReference = this.GetTypeDefinitionAtRow(classRowId); break; case TokenTypeIds.TypeRef: parentTypeReference = this.GetTypeRefReferenceAtRow(classRowId); break; case TokenTypeIds.TypeSpec: parentTypeReference = this.GetTypeSpecReferenceAtRow(owningObject, classRowId).UnderlyingModuleTypeReference; break; case TokenTypeIds.MethodDef: { var/*?*/ methodDef = this.GetMethodDefAtRow(classRowId); if (methodDef == null) { // Error... return null; } parentTypeReference = methodDef.ContainingType; break; } case TokenTypeIds.ModuleRef: { ModuleReference/*?*/ modRef = this.GetModuleReferenceAt(classRowId); if (modRef == null) { // MDError return null; } var module = this.ResolveModuleRefReference(modRef) as Module; if (module == null) { //TODO: MDError... return null; } PEFileToObjectModel modulePEFileToObjectModel = module.PEFileToObjectModel; parentTypeReference = modulePEFileToObjectModel._Module_; break; } default: { // MDError... return null; } } if (parentTypeReference == null) { // Error... return null; } MemberReference retModuleMemberReference; IName name = this.GetNameFromOffset(memberRefRow.Name); byte firstByte = this.PEFileReader.BlobStream.GetByteAt(memberRefRow.Signature, 0); var genericTypeInstance = parentTypeReference as IGenericTypeInstanceReference; var specializedNestedTypeReference = parentTypeReference as ISpecializedNestedTypeReference; if (SignatureHeader.IsFieldSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required FieldReference unspecializedFieldReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as FieldReference; if (unspecializedFieldReference == null) { unspecializedFieldReference = new FieldReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedFieldReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedFieldReference.InternedKey; var specializedField = this.SpecializedFieldHashtable.Find(key1, key2); if (specializedField == null) { specializedField = new SpecializedFieldReference(parentTypeReference, unspecializedFieldReference, this.InternFactory); this.SpecializedFieldHashtable.Add(key1, key2, specializedField); } return specializedField; } else { retModuleMemberReference = new FieldReference(this, memberRefRowId, parentTypeReference, name); } } else if (SignatureHeader.IsMethodSignature(firstByte)) { if (genericTypeInstance != null || specializedNestedTypeReference != null) { //The same memberRef token can be shared by distinct instance references, therefore special caching is required MethodReference unspecializedMethodReference = this.UnspecializedMemberReferenceArray[memberRefRowId] as MethodReference; if (unspecializedMethodReference == null) { unspecializedMethodReference = new MethodReference(this, memberRefRowId, TypeCache.Unspecialize(parentTypeReference), name, firstByte); this.UnspecializedMemberReferenceArray[memberRefRowId] = unspecializedMethodReference; } uint key1 = parentTypeReference.InternedKey; uint key2 = unspecializedMethodReference.InternedKey; var specializedMethod = this.SpecializedMethodHashtable.Find(key1, key2); if (specializedMethod == null) { specializedMethod = new SpecializedMethodReference(parentTypeReference, unspecializedMethodReference, this.InternFactory); this.SpecializedMethodHashtable.Add(key1, key2, specializedMethod); } return specializedMethod; } else { retModuleMemberReference = new MethodReference(this, memberRefRowId, parentTypeReference, name, firstByte); } } else { // MD Error return null; } this.ModuleMemberReferenceArray[memberRefRowId] = retModuleMemberReference; } MemberReference/*?*/ ret = this.ModuleMemberReferenceArray[memberRefRowId]; return ret; }
public CallMethodDescription(Instruction instruction) { this.instruction = instruction; targetMethod = (MethodReference)instruction.Operand; }
internal int GetMethodRefGenericParameterCount( MethodReference moduleMethodReference ) { uint signatureBlobOffset = this.PEFileReader.MemberRefTable.GetSignature(moduleMethodReference.MemberRefRowId); // TODO: error checking offset in range MemoryBlock signatureMemoryBlock = this.PEFileReader.BlobStream.GetMemoryBlockAt(signatureBlobOffset); // TODO: Error checking enough space in signature memoryBlock. MemoryReader memoryReader = new MemoryReader(signatureMemoryBlock); // TODO: Check if this is really method signature there. byte firstByte = memoryReader.ReadByte(); if (SignatureHeader.IsGeneric(firstByte)) { return memoryReader.ReadCompressedUInt32(); } return 0; }
protected virtual string GetConstructorName(MethodReference constructor) { return(constructor.Name); }
public void Emit(OpCode opcode, MethodReference method) { Append (Create (opcode, method)); }
protected virtual string GetMethodName(MethodReference method) { return(method.Name); }
public FluentEmitter Call(MethodReference m) { return Emit(OpCodes.Call, m); }
public Instruction CreateInstruction(OpCode opCode, MethodReference value) { return(Processor.Create(opCode, value)); }
/// <summary> /// Returns a reference to the closure method. If the method is generic, the reference is to an instantiation, /// using the generic parameters of the current class as arguments. /// </summary> private IMethodReference CreateClosureMethod(AnonymousDelegate anonymousDelegate) { bool isPeerMethod = this.helperMembers != null && !this.anonymousDelegatesThatCaptureLocalsOrParameters.ContainsKey(anonymousDelegate); bool isStaticMethod = isPeerMethod && !this.anonymousDelegatesThatCaptureThis.ContainsKey(anonymousDelegate); var body = new SourceMethodBody(this.host, this.sourceLocationProvider) { Block = anonymousDelegate.Body, LocalsAreZeroed = true }; var counter = isPeerMethod ? this.helperMembers.Count : this.anonymousDelegateCounter++; var prefix = "<"+this.method.Name.Value; prefix += isPeerMethod ? ">p__" : ">b__"; var method = new MethodDefinition() { ContainingTypeDefinition = isPeerMethod ? this.method.ContainingTypeDefinition : this.currentClosureClass, Name = this.host.NameTable.GetNameFor(prefix+counter), Visibility = isPeerMethod ? TypeMemberVisibility.Private : TypeMemberVisibility.Public, Body = body, CallingConvention = isStaticMethod ? CallingConvention.Default : CallingConvention.HasThis, InternFactory = this.host.InternFactory, Parameters = anonymousDelegate.Parameters, Type = anonymousDelegate.ReturnType, IsCil = true, IsStatic = isStaticMethod, IsHiddenBySignature = true, }; body.MethodDefinition = method; if (method.Parameters != null) { foreach (ParameterDefinition parameterDefinition in method.Parameters) parameterDefinition.ContainingSignature = method; } if (isPeerMethod) { this.helperMembers.Add(method); if (this.method.IsGeneric) this.MakeDelegateMethodGeneric(method); method.Attributes = new List<ICustomAttribute>(1); method.Attributes.Add(this.compilerGenerated); } else { this.currentClosureClass.Methods.Add(method); this.isInsideAnonymousMethod = true; this.RewriteChildren(method); this.isInsideAnonymousMethod = false; } IMethodReference methodReference = method; ITypeReference containingTypeDefinitionInstance = method.ContainingTypeDefinition; if (isPeerMethod) containingTypeDefinitionInstance = NamedTypeDefinition.SelfInstance((INamedTypeDefinition)method.ContainingTypeDefinition, this.host.InternFactory); if ((isPeerMethod && method.ContainingTypeDefinition != containingTypeDefinitionInstance) || (!isPeerMethod && this.currentClosureClass != this.currentClosureInstance)) { methodReference = new MethodReference() { CallingConvention = method.CallingConvention, ContainingType = isPeerMethod ? containingTypeDefinitionInstance : this.currentClosureInstance, GenericParameterCount = method.GenericParameterCount, InternFactory = this.host.InternFactory, Name = method.Name, Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters), Type = method.Type, }; } if (!method.IsGeneric) return methodReference; return new GenericMethodInstanceReference() { CallingConvention = method.CallingConvention, ContainingType = method.ContainingTypeDefinition, GenericArguments = new List<ITypeReference>(IteratorHelper.GetConversionEnumerable<IGenericMethodParameter, ITypeReference>(method.GenericParameters)), GenericMethod = methodReference, InternFactory = this.host.InternFactory, Name = method.Name, Parameters = methodReference.ParameterCount == 0 ? null : new List<IParameterTypeInformation>(methodReference.Parameters), Type = method.Type, }; }
public void AddInflatedMethod(MethodReference method) { this._inflatedMethods.Add(method); }
SecurityCustomAttribute/*?*/ ReadSecurityAttribute(SecurityAttribute securityAttribute) { string/*?*/ typeNameStr = this.GetSerializedString(); if (typeNameStr == null) return null; ITypeReference/*?*/ moduleTypeReference = this.PEFileToObjectModel.GetSerializedTypeNameAsTypeReference(typeNameStr); if (moduleTypeReference == null) return null; IMethodReference ctorReference = Dummy.MethodReference; ITypeDefinition attributeType = moduleTypeReference.ResolvedType; if (!(attributeType is Dummy)) { foreach (ITypeDefinitionMember member in attributeType.GetMembersNamed(this.PEFileToObjectModel.NameTable.Ctor, false)) { IMethodDefinition/*?*/ method = member as IMethodDefinition; if (method == null) continue; if (!IteratorHelper.EnumerableHasLength(method.Parameters, 1)) continue; //TODO: check that parameter has the right type ctorReference = method; break; } } else { int ctorKey = this.PEFileToObjectModel.NameTable.Ctor.UniqueKey; foreach (ITypeMemberReference mref in this.PEFileToObjectModel.GetMemberReferences()) { IMethodReference/*?*/ methRef = mref as IMethodReference; if (methRef == null) continue; if (methRef.ContainingType.InternedKey != moduleTypeReference.InternedKey) continue; if (methRef.Name.UniqueKey != ctorKey) continue; if (!IteratorHelper.EnumerableHasLength(methRef.Parameters, 1)) continue; //TODO: check that parameter has the right type ctorReference = methRef; break; } } if (ctorReference is Dummy) { ctorReference = new MethodReference(this.PEFileToObjectModel.ModuleReader.metadataReaderHost, moduleTypeReference, CallingConvention.Default|CallingConvention.HasThis, this.PEFileToObjectModel.PlatformType.SystemVoid, this.PEFileToObjectModel.NameTable.Ctor, 0, this.PEFileToObjectModel.PlatformType.SystemSecurityPermissionsSecurityAction); } this.SignatureMemoryReader.ReadCompressedUInt32(); // BlobSize... int numOfNamedArgs = this.SignatureMemoryReader.ReadCompressedUInt32(); FieldOrPropertyNamedArgumentExpression[]/*?*/ namedArgumentArray = null; if (numOfNamedArgs > 0) { namedArgumentArray = new FieldOrPropertyNamedArgumentExpression[numOfNamedArgs]; for (int i = 0; i < numOfNamedArgs; ++i) { bool isField = this.SignatureMemoryReader.ReadByte() == SerializationType.Field; ITypeReference/*?*/ memberType = this.GetFieldOrPropType(); if (memberType == null) return null; string/*?*/ memberStr = this.GetSerializedString(); if (memberStr == null) return null; IName memberName = this.PEFileToObjectModel.NameTable.GetNameFor(memberStr); ExpressionBase/*?*/ value = this.ReadSerializedValue(memberType); if (value == null) return null; namedArgumentArray[i] = new FieldOrPropertyNamedArgumentExpression(memberName, moduleTypeReference, isField, memberType, value); } } return new SecurityCustomAttribute(securityAttribute, ctorReference, namedArgumentArray); }
/// <summary> /// Returns a method on the type similar to the specified method. /// </summary> /// <param name="containingType">The type on which to resolve the method.</param> /// <param name="similarMethod">A reference to the similar method.</param> /// <param name="altName">Optionally, find a method similar to <paramref name="similarMethod"/>, but with this name instead.</param> /// <returns></returns> public static MethodDefinition GetMethodLike(this TypeDefinition containingType, MethodReference similarMethod, string altName = null) { Console.WriteLine("Method like"); return (containingType.GetMethods(altName ?? similarMethod.Name, similarMethod.Parameters.Select(x => x.ParameterType), similarMethod.GenericParameters.Count, similarMethod.ReturnType) .SingleOrDefault()); }