private AnalysisNet.IInstruction ProcessMethodCall(Cecil.Cil.Instruction op) { AnalysisNetBytecode.MethodCallOperation operation = OperationHelper.ToMethodCallOperation(op.OpCode.Code); Cecil.MethodReference cciMethod = op.Operand as Cecil.MethodReference; AnalysisNet.Types.IMethodReference ourMethod = typeExtractor.ExtractMethod(cciMethod); AnalysisNet.IInstruction instruction; if (ourMethod.ContainingType is FakeArrayType fakeArrayType) { AnalysisNet.Types.ArrayType arrayType = fakeArrayType.Type; if (ourMethod.Name == "Set") { instruction = ProcessStoreArrayElement(op, arrayType); return(instruction); } else { AnalysisNetBytecode.LoadArrayElementOperation arrayOp = OperationHelper.ToLoadArrayElementOperation(ourMethod.Name); instruction = ProcessLoadArrayElement(op, arrayOp, arrayType); return(instruction); } } instruction = new AnalysisNetBytecode.MethodCallInstruction((uint)op.Offset, operation, ourMethod); return(instruction); }
public AnalysisNet.Types.IMethodReference ExtractMethod(Cecil.MethodReference methodReference) { return(performanceCache.GetOrCreate(methodReference, (cacheEntry) => { if (methodReference is Cecil.GenericInstanceMethod instanceMethod) { List <AnalysisNet.Types.IType> genericArguments = new List <AnalysisNet.Types.IType>(); foreach (Cecil.TypeReference typeParameterref in instanceMethod.GenericArguments) { AnalysisNet.Types.IType typeArgumentref = ExtractType(typeParameterref); genericArguments.Add(typeArgumentref); } AnalysisNet.Types.IMethodReference method = ExtractMethod(instanceMethod.GetElementMethod()); AnalysisNet.Types.MethodReference instantiatedMethod = AnalysisNet.Extensions.Instantiate(method, genericArguments); instantiatedMethod.Resolve(host); return instantiatedMethod; } else { return ExtractNonGenericInstanceMethod(methodReference); } })); }
// call after every method definition in analysisNetType is extracted private void ExtractPropertyDefinitions(AnalysisNet.Types.TypeDefinition analysisNetType, Cecil.TypeDefinition cecilType) { foreach (Cecil.PropertyDefinition cecilProperty in cecilType.Properties) { AnalysisNet.Types.PropertyDefinition ourProp = new AnalysisNet.Types.PropertyDefinition(cecilProperty.Name, ExtractType(cecilProperty.PropertyType)) { ContainingType = analysisNetType }; if (cecilProperty.GetMethod != null) { // It is a reference but we need the definition. // It is not safe to call ResolvedMethod at this point, the model is incomplete. AnalysisNet.Types.IMethodReference getterRef = ExtractMethod(cecilProperty.GetMethod); ourProp.Getter = analysisNetType.Methods.Where(methodDef => methodDef.MatchSignature(getterRef)).First(); } if (cecilProperty.SetMethod != null) { // It is a reference but we need the definition. // It is not safe to call ResolvedMethod at this point, the model is incomplete. AnalysisNet.Types.IMethodReference setterRef = ExtractMethod(cecilProperty.SetMethod); ourProp.Setter = analysisNetType.Methods.Where(methodDef => methodDef.MatchSignature(setterRef)).First(); } ExtractCustomAttributes(ourProp.Attributes, cecilProperty.CustomAttributes); analysisNetType.PropertyDefinitions.Add(ourProp); } }
public Cecil.MethodReference MethodReference(AnalysisNet.Types.IMethodReference methodReference) { if (methodsCache.TryGetValue(methodReference, out Cecil.MethodReference cecilMethodReference)) { return(cecilMethodReference); } Cecil.TypeReference dummyReturnType = Context.CurrentModule.TypeSystem.Void; Cecil.TypeReference declaringType = TypeReference(methodReference.ContainingType); string name = methodReference.Name; cecilMethodReference = new Cecil.MethodReference(name, dummyReturnType, declaringType) { HasThis = !methodReference.IsStatic }; if (methodReference.GenericParameterCount > 0) { cecilMethodReference.CreateGenericParameters(methodReference.GenericParameterCount); MapGenericParameters(cecilMethodReference, methodReference); // should we add constraints? if (methodReference.GenericArguments.Count == 0) { Cecil.GenericInstanceMethod instantiated = new Cecil.GenericInstanceMethod(cecilMethodReference); instantiated.GenericArguments.AddRange(cecilMethodReference.GenericParameters); cecilMethodReference = instantiated; } else { IEnumerable <Cecil.TypeReference> arguments = methodReference.GenericArguments.Select(ga => TypeReference(ga)); Cecil.GenericInstanceMethod instantiated = new Cecil.GenericInstanceMethod(cecilMethodReference); instantiated.GenericArguments.AddRange(arguments); cecilMethodReference = instantiated; } } cecilMethodReference.ReturnType = TypeReference(methodReference.ReturnType); foreach (AnalysisNet.Types.IMethodParameterReference parameter in methodReference.Parameters) { Cecil.ParameterDefinition cecilParam = new Cecil.ParameterDefinition(TypeReference(parameter.Type)); if (parameter.Kind == AnalysisNet.Types.MethodParameterKind.In) { cecilParam.IsIn = true; } else if (parameter.Kind == AnalysisNet.Types.MethodParameterKind.Out) { cecilParam.IsOut = true; } cecilMethodReference.Parameters.Add(cecilParam); } cecilMethodReference = Context.CurrentModule.ImportReference(cecilMethodReference); methodsCache[methodReference] = cecilMethodReference; return(cecilMethodReference); }
private AnalysisNet.IInstruction ProcessLoadMethodAddress(Cecil.Cil.Instruction op) { AnalysisNetBytecode.LoadMethodAddressOperation operation = OperationHelper.ToLoadMethodAddressOperation(op.OpCode.Code); Cecil.MethodReference cciMethod = op.Operand as Cecil.MethodReference; AnalysisNet.Types.IMethodReference ourMethod = typeExtractor.ExtractMethod(cciMethod); AnalysisNetBytecode.LoadMethodAddressInstruction instruction = new AnalysisNetBytecode.LoadMethodAddressInstruction((uint)op.Offset, operation, ourMethod); return(instruction); }
private AnalysisNet.IInstruction ProcessCreateObject(Cecil.Cil.Instruction op) { Cecil.MethodReference cciMethod = op.Operand as Cecil.MethodReference; AnalysisNet.Types.IMethodReference ourMethod = typeExtractor.ExtractMethod(cciMethod); if (ourMethod.ContainingType is FakeArrayType fakeArrayType) { bool withLowerBounds = ourMethod.Parameters.Count > fakeArrayType.Type.Rank; return(CreateArray((uint)op.Offset, fakeArrayType.Type, withLowerBounds)); } AnalysisNetBytecode.CreateObjectInstruction instruction = new AnalysisNetBytecode.CreateObjectInstruction((uint)op.Offset, ourMethod); return(instruction); }
private void ExtractExplicitMethodOverrides(AnalysisNet.Types.TypeDefinition type, Cecil.TypeDefinition typeDefinition) { foreach (Cecil.MethodDefinition method in typeDefinition.Methods) { AnalysisNet.Types.IMethodReference implementingMethod = ExtractMethod(method); Mono.Collections.Generic.Collection <Cecil.MethodReference> overrides = method.Overrides; foreach (Cecil.MethodReference implemented in overrides) { AnalysisNet.Types.IMethodReference implementedMethod = ExtractMethod(implemented); AnalysisNet.Types.MethodImplementation methodImplementation = new AnalysisNet.Types.MethodImplementation(implementedMethod, implementingMethod); type.ExplicitOverrides.Add(methodImplementation); } } }