private AnalysisNet.IInstruction ProcessCreateArray(Cecil.Cil.Instruction op) { Cecil.ArrayType cciArrayType = Cecil.Rocks.TypeReferenceRocks.MakeArrayType(op.Operand as Cecil.TypeReference); AnalysisNet.Types.ArrayType ourArrayType = typeExtractor.ExtractType(cciArrayType) as AnalysisNet.Types.ArrayType; return(CreateArray((uint)op.Offset, ourArrayType)); }
private TypeReference ReplaceElementType(TypeSpecification ts, TypeReference newElementType) { var arrayType = ts as Mono.Cecil.ArrayType; if (arrayType != null) { if (newElementType == arrayType.ElementType) { return(arrayType); } var newArrayType = new Mono.Cecil.ArrayType(newElementType, arrayType.Rank); for (int dimension = 0; dimension < arrayType.Rank; dimension++) { newArrayType.Dimensions[dimension] = arrayType.Dimensions[dimension]; } return(newArrayType); } var byReferenceType = ts as Mono.Cecil.ByReferenceType; if (byReferenceType != null) { return(new Mono.Cecil.ByReferenceType(newElementType)); } // TODO: should we throw an exception instead calling Resolve method? return(ts.ResolveOrThrow()); }
private AnalysisNet.Types.ArrayType ExtractType(Cecil.ArrayType typeref) { AnalysisNet.Types.IType elements = ExtractType(typeref.ElementType); AnalysisNet.Types.ArrayType type = new AnalysisNet.Types.ArrayType(elements, (uint)typeref.Rank); return(type); }
public static bool IsEqualTo(this ArrayType a, ArrayType b) { if (a.Rank != b.Rank) { return false; } return true; }
protected virtual ArrayType updateArrayType(ArrayType a) { var rv = new ArrayType(update(a.ElementType)); if (!a.IsVector) { foreach (var dim in a.Dimensions) rv.Dimensions.Add(dim); } return rv; }
internal bool AreSame(ArrayType a, ArrayType b) { if (a.Rank != b.Rank) return false; // TODO: dimensions return true; }
public static bool IsSimilarType(Type thisType, Mono.Cecil.TypeReference type) { // Ignore any 'ref' types if (thisType.IsByRef) { thisType = thisType.GetElementType(); } if (type.IsByReference) { if (type.IsArray) { var array_type = type as ArrayType; type = array_type.ElementType; } else { type = type.GetElementType(); } } // Handle array types if (thisType.IsArray && type.IsArray) { Mono.Cecil.ArrayType at = type as Mono.Cecil.ArrayType; // Dimensions must be the same. if (thisType.GetArrayRank() != at.Rank) { return(false); } // Base type of array must be the same. var array_type = type as ArrayType; return(IsSimilarType(thisType.GetElementType(), array_type.ElementType)); } if (thisType.IsArray && !type.IsArray) { return(false); } if (type.IsArray && !thisType.IsArray) { return(false); } // If the types are identical, or they're both generic parameters // or the special 'T' type, treat as a match // Match also if thisType is generic and type can be unified with thisType. if (thisType.Name == type.Name || // identical types. ((thisType.IsGenericParameter || thisType == typeof(T)) && (type.IsGenericParameter || type.Name.Equals("T"))) || // using "T" as matching generic type. IsUnifiableMono(thisType, type)) { return(true); } return(false); }
bool TransformArrayInitializers(List<ILNode> body, ILExpression expr, int pos) { ILVariable v, v3; ILExpression newarrExpr; TypeReference elementType; ILExpression lengthExpr; int arrayLength; if (expr.Match(ILCode.Stloc, out v, out newarrExpr) && newarrExpr.Match(ILCode.Newarr, out elementType, out lengthExpr) && lengthExpr.Match(ILCode.Ldc_I4, out arrayLength) && arrayLength > 0) { ILExpression[] newArr; int initArrayPos; if (ForwardScanInitializeArrayRuntimeHelper(body, pos + 1, v, elementType, arrayLength, out newArr, out initArrayPos)) { var arrayType = new ArrayType(elementType, 1); arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength); body[pos] = new ILExpression(ILCode.Stloc, v, new ILExpression(ILCode.InitArray, arrayType, newArr)); body.RemoveAt(initArrayPos); } // Put in a limit so that we don't consume too much memory if the code allocates a huge array // and populates it extremely sparsly. However, 255 "null" elements in a row actually occur in the Mono C# compiler! const int maxConsecutiveDefaultValueExpressions = 300; List<ILExpression> operands = new List<ILExpression>(); int numberOfInstructionsToRemove = 0; for (int j = pos + 1; j < body.Count; j++) { ILExpression nextExpr = body[j] as ILExpression; int arrayPos; if (nextExpr != null && nextExpr.Code.IsStoreToArray() && nextExpr.Arguments[0].Match(ILCode.Ldloc, out v3) && v == v3 && nextExpr.Arguments[1].Match(ILCode.Ldc_I4, out arrayPos) && arrayPos >= operands.Count && arrayPos <= operands.Count + maxConsecutiveDefaultValueExpressions) { while (operands.Count < arrayPos) operands.Add(new ILExpression(ILCode.DefaultValue, elementType)); operands.Add(nextExpr.Arguments[2]); numberOfInstructionsToRemove++; } else { break; } } if (operands.Count == arrayLength) { var arrayType = new ArrayType(elementType, 1); arrayType.Dimensions[0] = new ArrayDimension(0, arrayLength); expr.Arguments[0] = new ILExpression(ILCode.InitArray, arrayType, operands); body.RemoveRange(pos + 1, numberOfInstructionsToRemove); new ILInlining(method).InlineIfPossible(body, ref pos); return true; } } return false; }
/// <summary> /// Loads the specified reflection Type and returns the equivalent CeCil TypeDefinition /// </summary> /// <returns>The loaded type.</returns> /// <param name="t">The type to load.</param> protected virtual TypeReference LoadType(Type t) { if (m_typelookup.ContainsKey(t)) { return(m_typelookup[t]); } AssemblyDefinition asm; m_assemblies.TryGetValue(t.Assembly.Location, out asm); if (asm == null) { asm = m_assemblies[t.Assembly.Location] = AssemblyDefinition.ReadAssembly(t.Assembly.Location); } if (asm == null) { return(null); } var res = LoadTypeByName(t.FullName, asm.Modules); if (res == null && t.IsGenericType) { var gt = t.GetGenericTypeDefinition(); var gtd = LoadTypeByName(gt.FullName, asm.Modules); if (gtd != null) { var gtr = new GenericInstanceType(gtd); foreach (var ga in t.GetGenericArguments().Select(x => LoadType(x))) { gtr.GenericArguments.Add(ga); } res = gtr; } } if (res == null && t.IsArray) { var el = t.GetElementType(); res = new Mono.Cecil.ArrayType(LoadType(el)); } if (res == null) { throw new Exception($"Failed to load {t.FullName}, the following types were found in the assembly: {string.Join(",", asm.Modules.SelectMany(x => x.GetTypes()).Select(x => x.FullName))}"); } return(m_typelookup[t] = res); }
private string WriteArrayDataValue(ArrayType arrayType) { base.Writer.WriteExternForIl2CppType(arrayType.ElementType); if (arrayType.Rank == 1) { return ("(void*)&" + MetadataWriter.Naming.ForIl2CppType(arrayType.ElementType, 0)); } object[] args = new object[] { MetadataWriter.Naming.ForArrayType(arrayType) }; base.WriteLine("Il2CppArrayType {0} = ", args); string[] initializers = new string[] { string.Format("&{0}", MetadataWriter.Naming.ForIl2CppType(arrayType.ElementType, 0)), arrayType.Rank.ToString(), 0.ToString(), 0.ToString(), MetadataWriter.Naming.Null, MetadataWriter.Naming.Null }; base.WriteArrayInitializer(initializers, MetadataWriter.ArrayTerminator.None); return ("&" + MetadataWriter.Naming.ForArrayType(arrayType)); }
public void ArrayTypeEquality () { var at1 = new ArrayType(T1); var at2 = new ArrayType(T2); var at3 = new ArrayType(T3); var at4 = new ArrayType(T1, 2); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, T1)); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, T1)); Assert.IsTrue(TypeUtil.TypesAreEqual(at1, at1)); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, at2)); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, at3)); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, at4, true)); Assert.IsFalse(TypeUtil.TypesAreEqual(at1, at4, false)); }
public override void Compile(Emitter.Emitter emitter) { var args = new[] { Parameters.Count == 1 ? typeof(object) : typeof(IEnumerable<dynamic>), typeof(bool) }; var printMethod = emitter.AssemblyImport(typeof(MirelleStdlib.Printer).GetMethod("Print", args)); if (Parameters.Count == 1) { var currType = Parameters[0].GetExpressionType(emitter); Parameters[0].Compile(emitter); if (currType.IsAnyOf("int", "bool", "float", "complex")) emitter.EmitBox(emitter.ResolveType(currType)); } else { var objType = emitter.AssemblyImport(typeof(object)); var arrType = new ArrayType(objType); var tmpVariable = emitter.CurrentMethod.Scope.Introduce("object[]", arrType); // load count & create emitter.EmitLoadInt(Parameters.Count); emitter.EmitNewArray(objType); emitter.EmitSaveVariable(tmpVariable); int idx = 0; foreach (var curr in Parameters) { var currType = curr.GetExpressionType(emitter); emitter.EmitLoadVariable(tmpVariable); emitter.EmitLoadInt(idx); curr.Compile(emitter); if (currType.IsAnyOf("int", "bool", "float", "complex")) emitter.EmitBox(emitter.ResolveType(currType)); emitter.EmitSaveIndex("object"); idx++; } // return the created array emitter.EmitLoadVariable(tmpVariable); } emitter.EmitLoadBool(PrintLine); emitter.EmitCall(printMethod); }
public ComSafeArrayMarshalInfoWriter(ArrayType type, MarshalInfo marshalInfo) : base(type) { this._elementType = type.ElementType; this._marshalInfo = marshalInfo as SafeArrayMarshalInfo; if (this._marshalInfo == null) { throw new InvalidOperationException(string.Format("SafeArray type '{0}' has invalid MarshalAsAttribute.", type.FullName)); } if ((this._marshalInfo.ElementType == VariantType.BStr) && (this._elementType.MetadataType != MetadataType.String)) { throw new InvalidOperationException(string.Format("SafeArray(BSTR) type '{0}' has invalid MarshalAsAttribute.", type.FullName)); } NativeType nativeElementType = this.GetNativeElementType(); this._elementTypeMarshalInfoWriter = MarshalDataCollector.MarshalInfoWriterFor(this._elementType, MarshalType.COM, new MarshalInfo(nativeElementType), false, false, false, null); string name = string.Format("Il2CppSafeArray/*{0}*/*", this._marshalInfo.ElementType.ToString().ToUpper()); this._marshaledTypes = new MarshaledType[] { new MarshaledType(name, name) }; }
TypeSpecification GetTypeSpec (TypeSpecification original, ImportContext context) { TypeSpecification typeSpec; TypeReference elementType = ImportTypeReference (original.ElementType, context); if (original is PointerType) { typeSpec = new PointerType (elementType); } else if (original is ArrayType) { // deal with complex arrays typeSpec = new ArrayType (elementType); } else if (original is ReferenceType) { typeSpec = new ReferenceType (elementType); } else if (original is GenericInstanceType) { GenericInstanceType git = original as GenericInstanceType; GenericInstanceType genElemType = new GenericInstanceType (elementType); context.GenericContext.CheckProvider (genElemType.GetOriginalType (), git.GenericArguments.Count); foreach (TypeReference arg in git.GenericArguments) genElemType.GenericArguments.Add (ImportTypeReference (arg, context)); typeSpec = genElemType; } else if (original is ModifierOptional) { TypeReference mt = (original as ModifierOptional).ModifierType; typeSpec = new ModifierOptional (elementType, ImportTypeReference (mt, context)); } else if (original is ModifierRequired) { TypeReference mt = (original as ModifierRequired).ModifierType; typeSpec = new ModifierRequired (elementType, ImportTypeReference (mt, context)); } else if (original is SentinelType) { typeSpec = new SentinelType (elementType); } else if (original is FunctionPointerType) { FunctionPointerType ori = original as FunctionPointerType; FunctionPointerType fnptr = new FunctionPointerType ( ori.HasThis, ori.ExplicitThis, ori.CallingConvention, new MethodReturnType (ImportTypeReference (ori.ReturnType.ReturnType, context))); foreach (ParameterDefinition parameter in ori.Parameters) fnptr.Parameters.Add (new ParameterDefinition (ImportTypeReference (parameter.ParameterType, context))); typeSpec = fnptr; } else throw new ReflectionException ("Unknown element type: {0}", original.GetType ().Name); return typeSpec; }
public override void Visit(Model.Bytecode.CreateArrayInstruction instruction) { Cecil.ArrayType cilArrayType = referenceGenerator.TypeReference(instruction.Type) as Cecil.ArrayType; Mono.Cecil.Cil.Instruction cilIns = null; if (!instruction.Type.IsVector) { Cecil.MethodReference arrayCtor = ArrayHelper.ArrayCtor(cilArrayType as Cecil.ArrayType); cilIns = processor.Create(Mono.Cecil.Cil.OpCodes.Newobj, arrayCtor); } else { cilIns = processor.Create(Mono.Cecil.Cil.OpCodes.Newarr, cilArrayType.ElementType); } Result = new List <Mono.Cecil.Cil.Instruction>() { cilIns }; }
/// <summary> /// Generates the Mono.Cecil TypeReference from its .NET <see cref="Type"/> counterpart. /// </summary> /// <param name="type">The type.</param> /// <param name="assemblyResolver">The assembly resolver.</param> /// <returns></returns> public static TypeReference GenerateTypeCecil(this Type type, BaseAssemblyResolver assemblyResolver) { var assemblyDefinition = assemblyResolver.Resolve(type.Assembly.FullName); TypeReference typeReference; if (type.IsNested) { var declaringType = GenerateTypeCecil(type.DeclaringType, assemblyResolver); typeReference = declaringType.Resolve().NestedTypes.FirstOrDefault(x => x.Name == type.Name); } else if (type.IsArray) { var elementType = GenerateTypeCecil(type.GetElementType(), assemblyResolver); typeReference = new ArrayType(elementType, type.GetArrayRank()); } else { typeReference = assemblyDefinition.MainModule.GetTypeResolved(type.IsGenericType ? type.GetGenericTypeDefinition().FullName : type.FullName); } if (typeReference == null) throw new InvalidOperationException("Could not resolve cecil type."); if (type.IsGenericType) { var genericInstanceType = new GenericInstanceType(typeReference); foreach (var argType in type.GetGenericArguments()) { TypeReference argTypeReference; if (argType.IsGenericParameter) { argTypeReference = new GenericParameter(argType.Name, typeReference); } else { argTypeReference = GenerateTypeCecil(argType, assemblyResolver); } genericInstanceType.GenericArguments.Add(argTypeReference); } typeReference = genericInstanceType; } return typeReference; }
private TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context) { switch (type.etype) { case ElementType.SzArray: { ArrayType arrayType = (ArrayType)type; return(new ArrayType(ImportType(arrayType.ElementType, context))); } case ElementType.Ptr: { PointerType pointerType = (PointerType)type; return(new PointerType(ImportType(pointerType.ElementType, context))); } case ElementType.ByRef: { ByReferenceType byReferenceType = (ByReferenceType)type; return(new ByReferenceType(ImportType(byReferenceType.ElementType, context))); } case ElementType.Pinned: { PinnedType pinnedType = (PinnedType)type; return(new PinnedType(ImportType(pinnedType.ElementType, context))); } case ElementType.Sentinel: { SentinelType sentinelType = (SentinelType)type; return(new SentinelType(ImportType(sentinelType.ElementType, context))); } case ElementType.FnPtr: { FunctionPointerType functionPointerType = (FunctionPointerType)type; FunctionPointerType functionPointerType2 = new FunctionPointerType { HasThis = functionPointerType.HasThis, ExplicitThis = functionPointerType.ExplicitThis, CallingConvention = functionPointerType.CallingConvention, ReturnType = ImportType(functionPointerType.ReturnType, context) }; if (!functionPointerType.HasParameters) { return(functionPointerType2); } for (int j = 0; j < functionPointerType.Parameters.Count; j++) { functionPointerType2.Parameters.Add(new ParameterDefinition(ImportType(functionPointerType.Parameters[j].ParameterType, context))); } return(functionPointerType2); } case ElementType.CModOpt: { OptionalModifierType optionalModifierType = (OptionalModifierType)type; return(new OptionalModifierType(ImportType(optionalModifierType.ModifierType, context), ImportType(optionalModifierType.ElementType, context))); } case ElementType.CModReqD: { RequiredModifierType requiredModifierType = (RequiredModifierType)type; return(new RequiredModifierType(ImportType(requiredModifierType.ModifierType, context), ImportType(requiredModifierType.ElementType, context))); } case ElementType.Array: { ArrayType arrayType2 = (ArrayType)type; ArrayType arrayType3 = new ArrayType(ImportType(arrayType2.ElementType, context)); if (arrayType2.IsVector) { return(arrayType3); } Collection <ArrayDimension> dimensions = arrayType2.Dimensions; Collection <ArrayDimension> dimensions2 = arrayType3.Dimensions; dimensions2.Clear(); for (int k = 0; k < dimensions.Count; k++) { ArrayDimension arrayDimension = dimensions[k]; dimensions2.Add(new ArrayDimension(arrayDimension.LowerBound, arrayDimension.UpperBound)); } return(arrayType3); } case ElementType.GenericInst: { GenericInstanceType genericInstanceType = (GenericInstanceType)type; GenericInstanceType genericInstanceType2 = new GenericInstanceType(ImportType(genericInstanceType.ElementType, context)); Collection <TypeReference> genericArguments = genericInstanceType.GenericArguments; Collection <TypeReference> genericArguments2 = genericInstanceType2.GenericArguments; for (int i = 0; i < genericArguments.Count; i++) { genericArguments2.Add(ImportType(genericArguments[i], context)); } return(genericInstanceType2); } case ElementType.Var: { GenericParameter genericParameter2 = (GenericParameter)type; if (genericParameter2.DeclaringType == null) { throw new InvalidOperationException(); } return(context.TypeParameter(genericParameter2.DeclaringType.FullName, genericParameter2.Position)); } case ElementType.MVar: { GenericParameter genericParameter = (GenericParameter)type; if (genericParameter.DeclaringMethod == null) { throw new InvalidOperationException(); } return(context.MethodParameter(context.NormalizeMethodName(genericParameter.DeclaringMethod), genericParameter.Position)); } default: throw new NotSupportedException(type.etype.ToString()); } }
TypeReference GetTypeSpec (Type t, ImportContext context) { Stack s = new Stack (); while (t.HasElementType || IsGenericTypeSpec (t)) { s.Push (t); if (t.HasElementType) t = t.GetElementType (); else if (IsGenericTypeSpec (t)) { t = (Type) t.GetType ().GetMethod ("GetGenericTypeDefinition").Invoke (t, null); break; } } TypeReference elementType = ImportSystemType (t, context); while (s.Count > 0) { t = (Type) s.Pop (); if (t.IsPointer) elementType = new PointerType (elementType); else if (t.IsArray) elementType = new ArrayType (elementType, t.GetArrayRank ()); else if (t.IsByRef) elementType = new ReferenceType (elementType); else if (IsGenericTypeSpec (t)) elementType = GetGenericType (t, elementType, context); else throw new ReflectionException ("Unknown element type"); } return elementType; }
public static ArrayType ChangeArrayType(this ArrayType type, TypeReference elementType, int rank) { if (elementType != type.ElementType || rank != type.Rank) { var result = new ArrayType(elementType, rank); if (type.HasGenericParameters) SetGenericParameters(result, type.GenericParameters); return result; } return type; }
void addArrayType(ArrayType at) { if (at == null) return; addTypeSpecification(at); }
private void ImportStilettoReferences(ModuleDefinition module, StilettoReferences stilettoReferences) { Binding = module.Import(stilettoReferences.Binding); Binding_Ctor = module.Import(stilettoReferences.Binding_Ctor); Binding_GetDependencies = module.Import(stilettoReferences.Binding_GetDependencies); Binding_Resolve = module.Import(stilettoReferences.Binding_Resolve); Binding_Get = module.Import(stilettoReferences.Binding_Get); Binding_InjectProperties = module.Import(stilettoReferences.Binding_InjectProperties); Binding_RequiredByGetter = module.Import(stilettoReferences.Binding_RequiredBy_Getter); Binding_IsLibrarySetter = module.Import(stilettoReferences.Binding_IsLibrary_Setter); BindingArray = new ArrayType(Binding); ProviderMethodBindingBase = module.Import(stilettoReferences.ProviderMethodBindingBase); ProviderMethodBindingBase_Ctor = module.Import(stilettoReferences.ProviderMethodBindingBase_Ctor); RuntimeModule = module.Import(stilettoReferences.RuntimeModule); RuntimeModule_Ctor = module.Import(stilettoReferences.RuntimeModule_Ctor); RuntimeModule_ModuleGetter = module.Import(stilettoReferences.RuntimeModule_Module_Getter); Container = module.Import(stilettoReferences.Container); Container_Create = module.Import(stilettoReferences.Container_Create); Container_CreateWithPlugins = module.Import(stilettoReferences.Container_CreateWithPlugins); IPlugin = module.Import(stilettoReferences.IPlugin); IPlugin_GetInjectBinding = module.Import(stilettoReferences.IPlugin_GetInjectBinding); IPlugin_GetLazyInjectBinding = module.Import(stilettoReferences.IPlugin_GetLazyInjectBinding); IPlugin_GetIProviderInjectBinding = module.Import(stilettoReferences.IPlugin_GetIProviderInjectBinding); IPlugin_GetRuntimeModue = module.Import(stilettoReferences.IPlugin_GetRuntimeModue); IProviderOfT = module.Import(stilettoReferences.IProviderOfT); IProviderOfT_Get = module.Import(stilettoReferences.IProviderOfT_Get); Resolver = module.Import(stilettoReferences.Resolver); Resolver_RequestBinding = module.Import(stilettoReferences.Resolver_RequestBinding); InjectAttribute = module.Import(stilettoReferences.InjectAttribute); ModuleAttribute = module.Import(stilettoReferences.ModuleAttribute); ProvidesAttribute = module.Import(stilettoReferences.ProvidesAttribute); NamedAttribute = module.Import(stilettoReferences.NamedAttribute); SingletonAttribute = module.Import(stilettoReferences.SingletonAttribute); ProcessedAssemblyAttribute = module.Import(stilettoReferences.ProcessedAssemblyAttribute); ProcessedAssemblyAttribute_Ctor = module.Import(stilettoReferences.ProcessedAssemblyAttribute_Ctor); }
public void Decorate(TypeDefinition type, MethodDefinition method, CustomAttribute attribute) { method.Body.InitLocals = true; var methodBaseTypeRef = this._referenceFinder.GetTypeReference(typeof(MethodBase)); var exceptionTypeRef = this._referenceFinder.GetTypeReference(typeof(Exception)); var parameterTypeRef = this._referenceFinder.GetTypeReference(typeof(object)); var parametersArrayTypeRef = new ArrayType(parameterTypeRef); var methodVariableDefinition = AddVariableDefinition(method, "__fody$method", methodBaseTypeRef); var attributeVariableDefinition = AddVariableDefinition(method, "__fody$attribute", attribute.AttributeType); var exceptionVariableDefinition = AddVariableDefinition(method, "__fody$exception", exceptionTypeRef); var parametersVariableDefinition = AddVariableDefinition(method, "__fody$parameters", parametersArrayTypeRef); VariableDefinition retvalVariableDefinition = null; if (method.ReturnType.FullName != "System.Void") retvalVariableDefinition = AddVariableDefinition(method, "__fody$retval", method.ReturnType); var initMethodRef = this._referenceFinder.GetOptionalMethodReference(attribute.AttributeType, md => md.Name == "Init"); var onEntryMethodRef = this._referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnEntry"); var onExitMethodRef = this._referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnExit"); var onExceptionMethodRef = this._referenceFinder.GetMethodReference(attribute.AttributeType, md => md.Name == "OnException"); var taskContinuationMethodRef = this._referenceFinder.GetOptionalMethodReference(attribute.AttributeType, md => md.Name == "OnTaskContinuation"); var processor = method.Body.GetILProcessor(); var methodBodyFirstInstruction = method.Body.Instructions.First(); if (method.IsConstructor && method.Body.Instructions.Any(i => i.OpCode == OpCodes.Call)) { methodBodyFirstInstruction = method.Body.Instructions.First(i => i.OpCode == OpCodes.Call).Next; } var initAttributeVariable = this.GetAttributeInstanceInstructions(processor, attribute, method, attributeVariableDefinition, methodVariableDefinition); IEnumerable<Instruction> callInitInstructions = null, createParametersArrayInstructions = null; if (null != initMethodRef) { createParametersArrayInstructions = CreateParametersArrayInstructions( processor, method, parameterTypeRef, parametersVariableDefinition); callInitInstructions = GetCallInitInstructions( processor, type, method, attributeVariableDefinition, methodVariableDefinition, parametersVariableDefinition, initMethodRef); } var callOnEntryInstructions = GetCallOnEntryInstructions(processor, attributeVariableDefinition, onEntryMethodRef); var saveRetvalInstructions = GetSaveRetvalInstructions(processor, retvalVariableDefinition); var callOnExitInstructions = GetCallOnExitInstructions(processor, attributeVariableDefinition, onExitMethodRef); var methodBodyReturnInstructions = GetMethodBodyReturnInstructions(processor, retvalVariableDefinition); var methodBodyReturnInstruction = methodBodyReturnInstructions.First(); var tryCatchLeaveInstructions = GetTryCatchLeaveInstructions(processor, methodBodyReturnInstruction); var catchHandlerInstructions = GetCatchHandlerInstructions(processor, attributeVariableDefinition, exceptionVariableDefinition, onExceptionMethodRef); ReplaceRetInstructions(processor, saveRetvalInstructions.Concat(callOnExitInstructions).First()); processor.InsertBefore(methodBodyFirstInstruction, initAttributeVariable); if (null != initMethodRef) { processor.InsertBefore(methodBodyFirstInstruction, createParametersArrayInstructions); processor.InsertBefore(methodBodyFirstInstruction, callInitInstructions); } processor.InsertBefore(methodBodyFirstInstruction, callOnEntryInstructions); processor.InsertAfter(method.Body.Instructions.Last(), methodBodyReturnInstructions); processor.InsertBefore(methodBodyReturnInstruction, saveRetvalInstructions); if (null != taskContinuationMethodRef) { var taskContinuationInstructions = GetTaskContinuationInstructions( processor, retvalVariableDefinition, attributeVariableDefinition, taskContinuationMethodRef); processor.InsertBefore(methodBodyReturnInstruction, taskContinuationInstructions); } processor.InsertBefore(methodBodyReturnInstruction, callOnExitInstructions); processor.InsertBefore(methodBodyReturnInstruction, tryCatchLeaveInstructions); processor.InsertBefore(methodBodyReturnInstruction, catchHandlerInstructions); method.Body.ExceptionHandlers.Add(new ExceptionHandler(ExceptionHandlerType.Catch) { CatchType = exceptionTypeRef, TryStart = methodBodyFirstInstruction, TryEnd = tryCatchLeaveInstructions.Last().Next, HandlerStart = catchHandlerInstructions.First(), HandlerEnd = catchHandlerInstructions.Last().Next }); }
TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context) { switch (type.etype) { case ElementType.SzArray: var vector = (ArrayType)type; return(new ArrayType(ImportType(vector.ElementType, context))); case ElementType.Ptr: var pointer = (PointerType)type; return(new PointerType(ImportType(pointer.ElementType, context))); case ElementType.ByRef: var byref = (ByReferenceType)type; return(new ByReferenceType(ImportType(byref.ElementType, context))); case ElementType.Pinned: var pinned = (PinnedType)type; return(new PinnedType(ImportType(pinned.ElementType, context))); case ElementType.Sentinel: var sentinel = (SentinelType)type; return(new SentinelType(ImportType(sentinel.ElementType, context))); case ElementType.FnPtr: var fnptr = (FunctionPointerType)type; var imported_fnptr = new FunctionPointerType() { HasThis = fnptr.HasThis, ExplicitThis = fnptr.ExplicitThis, CallingConvention = fnptr.CallingConvention, ReturnType = ImportType(fnptr.ReturnType, context), }; if (!fnptr.HasParameters) { return(imported_fnptr); } for (int i = 0; i < fnptr.Parameters.Count; i++) { imported_fnptr.Parameters.Add(new ParameterDefinition( ImportType(fnptr.Parameters [i].ParameterType, context))); } return(imported_fnptr); case ElementType.CModOpt: var modopt = (OptionalModifierType)type; return(new OptionalModifierType( ImportType(modopt.ModifierType, context), ImportType(modopt.ElementType, context))); case ElementType.CModReqD: var modreq = (RequiredModifierType)type; return(new RequiredModifierType( ImportType(modreq.ModifierType, context), ImportType(modreq.ElementType, context))); case ElementType.Array: var array = (ArrayType)type; var imported_array = new ArrayType(ImportType(array.ElementType, context)); if (array.IsVector) { return(imported_array); } var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear(); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions [i]; imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); } return(imported_array); case ElementType.GenericInst: var instance = (GenericInstanceType)type; var element_type = ImportType(instance.ElementType, context); var imported_instance = new GenericInstanceType(element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) { imported_arguments.Add(ImportType(arguments [i], context)); } return(imported_instance); case ElementType.Var: var var_parameter = (GenericParameter)type; if (var_parameter.DeclaringType == null) { throw new InvalidOperationException(); } return(context.TypeParameter(var_parameter.DeclaringType.FullName, var_parameter.Position)); case ElementType.MVar: var mvar_parameter = (GenericParameter)type; if (mvar_parameter.DeclaringMethod == null) { throw new InvalidOperationException(); } return(context.MethodParameter(mvar_parameter.DeclaringMethod.Name, mvar_parameter.Position)); } throw new NotSupportedException(type.etype.ToString()); }
private TypeReference GetFixedReturnType(TypeReference type) { if (type == null) { return(null); } if (type.IsOptionalModifier) { OptionalModifierType omt = (OptionalModifierType)type; TypeReference fixedElement = GetFixedReturnType(omt.ElementType); return(new OptionalModifierType(omt.ModifierType, fixedElement)); } if (type.IsRequiredModifier) { RequiredModifierType rmt = (RequiredModifierType)type; TypeReference fixedElement = GetFixedReturnType(rmt.ElementType); return(new RequiredModifierType(rmt.ModifierType, fixedElement)); } if (type.IsGenericParameter) { return(GetActualType(type)); } if (type.IsArray) { ArrayType at = (ArrayType)type; int rank = at.Rank; TypeReference arrayElementType = at.ElementType; arrayElementType = GetFixedReturnType(arrayElementType); return(new ArrayType(arrayElementType, rank)); } if (type.IsPointer) { TypeReference fixedElement = GetFixedReturnType(((PointerType)type).ElementType); return(new PointerType(fixedElement)); } if (type.IsByReference) { TypeReference fixedElement = GetFixedReturnType(((ByReferenceType)type).ElementType); return(new ByReferenceType(fixedElement)); } if (type.IsGenericInstance && DeclaringType.IsGenericInstance) { GenericInstanceType result = type as GenericInstanceType; GenericInstanceType declaringTypeGenericInstance = DeclaringType as GenericInstanceType; TypeReference declaringElementType = DeclaringType.GetElementType(); for (int i = 0; i < result.GenericArguments.Count; i++) { GenericParameter currentParam = result.GenericArguments[i] as GenericParameter; if (currentParam != null && currentParam.Owner == declaringElementType) { if (declaringTypeGenericInstance.PostionToArgument.ContainsKey(currentParam.Position)) { result.ReplaceGenericArgumentAt(i, declaringTypeGenericInstance.PostionToArgument[currentParam.position]); } } } return(result); } return(type); }
private static ArrayType ResolveIfNeeded(IGenericInstance genericInstanceMethod, IGenericInstance genericInstanceType, ArrayType arrayType) { return(new ArrayType(ResolveIfNeeded(genericInstanceMethod, genericInstanceType, arrayType.ElementType), arrayType.Rank)); }
TypeSpecification GetTypeSpec (TypeSpecification original, ImportContext context) { TypeSpecification typeSpec; TypeReference elementType = ImportTypeReference (original.ElementType, context); if (original is PointerType) { typeSpec = new PointerType (elementType); } else if (original is ArrayType) // deal with complex arrays { typeSpec = new ArrayType (elementType); } else if (original is ReferenceType) { typeSpec = new ReferenceType (elementType); } else if (original is GenericInstanceType) { GenericInstanceType git = original as GenericInstanceType; GenericInstanceType genElemType = new GenericInstanceType (elementType); context.GenericContext.CheckProvider (genElemType.GetOriginalType (), git.GenericArguments.Count); foreach (TypeReference arg in git.GenericArguments) genElemType.GenericArguments.Add (ImportTypeReference (arg, context)); typeSpec = genElemType; } else if (original is ModifierOptional) { TypeReference mt = (original as ModifierOptional).ModifierType; typeSpec = new ModifierOptional (elementType, ImportTypeReference (mt, context)); } else if (original is ModifierRequired) { TypeReference mt = (original as ModifierRequired).ModifierType; typeSpec = new ModifierRequired (elementType, ImportTypeReference (mt, context)); } else if (original is SentinelType) { typeSpec = new SentinelType (elementType); } else if (original is FunctionPointerType) { FunctionPointerType ori = original as FunctionPointerType; FunctionPointerType fnptr = new FunctionPointerType ( ori.HasThis, ori.ExplicitThis, ori.CallingConvention, new MethodReturnType (ImportTypeReference (ori.ReturnType.ReturnType, context))); foreach (ParameterDefinition parameter in ori.Parameters) fnptr.Parameters.Add (new ParameterDefinition (ImportTypeReference (parameter.ParameterType, context))); typeSpec = fnptr; } else throw new ReflectionException ("Unknown element type: {0}", original.GetType ().Name); return typeSpec; }
static void AppendTypeName(StringBuilder b, TypeReference type) { if (type == null) { // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies return; } if (type is GenericInstanceType) { GenericInstanceType giType = (GenericInstanceType)type; AppendTypeNameWithArguments(b, giType.ElementType, giType.GenericArguments); } else if (type is TypeSpecification) { AppendTypeName(b, ((TypeSpecification)type).ElementType); ArrayType arrayType = type as ArrayType; if (arrayType != null) { b.Append('['); for (int i = 0; i < arrayType.Dimensions.Count; i++) { if (i > 0) { b.Append(','); } ArrayDimension ad = arrayType.Dimensions[i]; if (ad.IsSized) { b.Append(ad.LowerBound); b.Append(':'); b.Append(ad.UpperBound); } } b.Append(']'); } ByReferenceType refType = type as ByReferenceType; if (refType != null) { b.Append('@'); } PointerType ptrType = type as PointerType; if (ptrType != null) { b.Append('*'); } } else { GenericParameter gp = type as GenericParameter; if (gp != null) { b.Append('`'); if (gp.Owner.GenericParameterType == GenericParameterType.Method) { b.Append('`'); } b.Append(gp.Position); } else if (type.DeclaringType != null) { AppendTypeName(b, type.DeclaringType); b.Append('.'); b.Append(type.Name); } else { b.Append(type.FullName); } } }
/// <summary> /// Check the given type. /// </summary> private bool Check(ArrayType type, string context) { return Check(type.ElementType, context); }
public TypeReference FixPlatformVersion(TypeReference reference) { if (targetPlatformDirectory == null) return reference; AssemblyNameReference scopeAsm = reference.Scope as AssemblyNameReference; if (scopeAsm != null) { AssemblyDefinition platformAsm = TryGetPlatformAssembly(scopeAsm); if (platformAsm != null) { TypeReference newTypeRef; if (reference is TypeSpecification) { TypeSpecification refSpec = reference as TypeSpecification; TypeReference fet = FixPlatformVersion(refSpec.ElementType); if (reference is ArrayType) { var array = (ArrayType)reference; var imported_array = new ArrayType(fet); if (array.IsVector) return imported_array; var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear(); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions[i]; imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); } return imported_array; } else if (reference is PointerType) return new PointerType(fet); else if (reference is ByReferenceType) return new ByReferenceType(fet); else if (reference is PinnedType) return new PinnedType(fet); else if (reference is SentinelType) return new SentinelType(fet); else if (reference is OptionalModifierType) return new OptionalModifierType(FixPlatformVersion(((OptionalModifierType)reference).ModifierType), fet); else if (reference is RequiredModifierType) return new RequiredModifierType(FixPlatformVersion(((RequiredModifierType)reference).ModifierType), fet); else if (reference is GenericInstanceType) { var instance = (GenericInstanceType)reference; var element_type = FixPlatformVersion(instance.ElementType); var imported_instance = new GenericInstanceType(element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) imported_arguments.Add(FixPlatformVersion(arguments[i])); return imported_instance; } else if (reference is FunctionPointerType) throw new NotImplementedException(); else throw new InvalidOperationException(); } else { newTypeRef = new TypeReference(reference.Namespace, reference.Name, reference.Module, platformAsm.Name); } foreach (var gp in reference.GenericParameters) newTypeRef.GenericParameters.Add(FixPlatformVersion(gp, newTypeRef)); newTypeRef.IsValueType = reference.IsValueType; if (reference.DeclaringType != null) newTypeRef.DeclaringType = FixPlatformVersion(reference.DeclaringType); return newTypeRef; } } return reference; }
/* * // Check if 'type' has some decorations applied to it * if (type is Mono.Cecil.TypeSpecification) { * // Go through all levels of 'indirection', 'array dimensions' * // and 'generic types' - in the end, we should get the actual * // type of the ReturnType (but all data about its array * // dimensions, levels of indirection and even its generic * // parameters is correctly stored within ArrayCount and * // ArrayDimensions, PointerNestingLevel and GenericArguments * // respectively). * if (type is ArrayType) { * // This return type is obviously an array - add the rank * ArrayType at = (ArrayType) type; * if (arrays == null) * arrays = new Stack<int>(); * arrays.Push(at.Rank); * type = at.ElementType; * } else else if (type is Mono.Cecil.ReferenceType) { * Mono.Cecil.ReferenceType rt = (Mono.Cecil.ReferenceType) type; * byRef = true; * type = rt.ElementType; * } else if (type is PointerType) { * // The type is a pointer * PointerType pt = (PointerType) type; ++pointerNestingLevel; * type = pt.ElementType; * // Go down one level * } else { * // TODO: Check if we loose some relevant info here * type = ((TypeSpecification)type).ElementType; * }*/ public static DomReturnType GetReturnType(TypeReference typeReference) { if (typeReference == null) { return(new DomReturnType(DomReturnType.Void.ToInvariantString())); } if (typeReference is Mono.Cecil.GenericInstanceType) { Mono.Cecil.GenericInstanceType genType = (Mono.Cecil.GenericInstanceType)typeReference; DomReturnType result = GetReturnType(genType.ElementType); foreach (TypeReference typeRef in genType.GenericArguments) { DomReturnType param = GetReturnType(typeRef); foreach (IReturnTypePart part in result.Parts) { if (part.Tag is TypeDefinition) { TypeDefinition typeDef = (TypeDefinition)part.Tag; foreach (TypeReference typeParam in typeDef.GenericParameters) { if (typeParam.Name == param.Name) { part.AddTypeParameter(param); goto skip; } } } } result.AddTypeParameter(param); skip :; } return(result); } if (typeReference is Mono.Cecil.ArrayType) { Mono.Cecil.ArrayType arrType = (Mono.Cecil.ArrayType)typeReference; DomReturnType result = GetReturnType(arrType.ElementType); result.ArrayDimensions++; result.SetDimension(result.ArrayDimensions - 1, arrType.Rank - 1); return(result); } if (typeReference is Mono.Cecil.PointerType) { Mono.Cecil.PointerType ptrType = (Mono.Cecil.PointerType)typeReference; DomReturnType result = GetReturnType(ptrType.ElementType); if (result.ArrayDimensions > 0) { result.ArrayPointerNestingLevel++; } else { result.PointerNestingLevel++; } return(result); } if (typeReference is Mono.Cecil.ByReferenceType) { return(GetReturnType(((Mono.Cecil.ByReferenceType)typeReference).ElementType)); } if (typeReference is Mono.Cecil.TypeDefinition) { Mono.Cecil.TypeDefinition typeDefinition = (Mono.Cecil.TypeDefinition)typeReference; DomReturnType result; if (typeDefinition.DeclaringType != null) { result = GetReturnType(typeDefinition.DeclaringType); result.Parts.Add(new ReturnTypePart(typeDefinition.Name)); result.Tag = typeDefinition; } else { result = new DomReturnType(typeDefinition.Name); result.Namespace = typeDefinition.Namespace; result.Tag = typeDefinition; } return(result); } return(new DomReturnType(DomCecilType.RemoveGenericParamSuffix(typeReference.FullName))); }
private TypeSpecification Fix(TypeSpecification type) { var fet = Fix(type.ElementType); if (type is ArrayType) { var array = (ArrayType)type; var imported_array = new ArrayType(fet); if (array.IsVector) return imported_array; var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear(); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions[i]; imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); } return imported_array; } if (type is PointerType) return new PointerType(fet); if (type is ByReferenceType) return new ByReferenceType(fet); if (type is PinnedType) return new PinnedType(fet); if (type is SentinelType) return new SentinelType(fet); if (type is OptionalModifierType) { TypeReference fmt = Fix(((OptionalModifierType)type).ModifierType); return new OptionalModifierType(fmt, fet); } if (type is RequiredModifierType) { TypeReference fmt = Fix(((RequiredModifierType)type).ModifierType); return new RequiredModifierType(fmt, fet); } if (type is GenericInstanceType) { var instance = (GenericInstanceType)type; var imported_instance = new GenericInstanceType(fet); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) imported_arguments.Add(Fix(arguments[i])); return imported_instance; } if (type is FunctionPointerType) { var funcPtr = (FunctionPointerType)type; var imported_instance = new FunctionPointerType() { HasThis = funcPtr.HasThis, ExplicitThis = funcPtr.ExplicitThis, CallingConvention = funcPtr.CallingConvention, ReturnType = Fix(funcPtr.ReturnType) }; if (funcPtr.HasParameters) { foreach (var pd in funcPtr.Parameters) { imported_instance.Parameters.Add(pd); } FixReferences(imported_instance.Parameters); } return imported_instance; } throw new InvalidOperationException(); }
private TypeReference ResolveGenericType(TypeReference originalType, IList<TypeReference> instanceArgs, IList<TypeReference> methodArgs) { TypeReference resolvedType = originalType; // if generic instance, copy generic arguments by recursing into them and building a 'resolved' argument list if (originalType is GenericInstanceType) { var originalGeneric = originalType as GenericInstanceType; var resolvedGeneric = new GenericInstanceType(originalGeneric.ElementType); resolvedType = resolvedGeneric; foreach (var originalArg in originalGeneric.GenericArguments) resolvedGeneric.GenericArguments.Add( ResolveGenericType(originalArg, instanceArgs, methodArgs)); } // if parameter, resolve it using the instance/method generice mapping lists else if (originalType is GenericParameter) { var originalParam = originalType as GenericParameter; if (originalParam.Type == GenericParameterType.Type) resolvedType = instanceArgs[originalParam.Position]; else if (originalParam.Type == GenericParameterType.Method) resolvedType = methodArgs[originalParam.Position]; } else if (originalType is ArrayType) { var originalArray = originalType as ArrayType; resolvedType = new ArrayType(ResolveGenericType(originalArray.ElementType, instanceArgs, methodArgs)); } else if (originalType is ByReferenceType) { var originalByRef = originalType as ByReferenceType; resolvedType = new ByReferenceType(ResolveGenericType(originalByRef.ElementType, instanceArgs, methodArgs)); } return resolvedType; }
TypeReference ImportTypeSpecification(TypeReference type, IGenericContext context) { switch (type.etype) { case ElementType.SzArray: var vector = (ArrayType)type; return(new ArrayType(ImportType(vector.ElementType, context))); case ElementType.Ptr: var pointer = (PointerType)type; return(new PointerType(ImportType(pointer.ElementType, context))); case ElementType.ByRef: var byref = (ByReferenceType)type; return(new ByReferenceType(ImportType(byref.ElementType, context))); case ElementType.Pinned: var pinned = (PinnedType)type; return(new PinnedType(ImportType(pinned.ElementType, context))); case ElementType.Sentinel: var sentinel = (SentinelType)type; return(new SentinelType(ImportType(sentinel.ElementType, context))); case ElementType.CModOpt: var modopt = (OptionalModifierType)type; return(new OptionalModifierType( ImportType(modopt.ModifierType, context), ImportType(modopt.ElementType, context))); case ElementType.CModReqD: var modreq = (RequiredModifierType)type; return(new RequiredModifierType( ImportType(modreq.ModifierType, context), ImportType(modreq.ElementType, context))); case ElementType.Array: var array = (ArrayType)type; var imported_array = new ArrayType(ImportType(array.ElementType, context)); if (array.IsVector) { return(imported_array); } var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear(); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions [i]; imported_dimensions.Add(new ArrayDimension(dimension.LowerBound, dimension.UpperBound)); } return(imported_array); case ElementType.GenericInst: var instance = (GenericInstanceType)type; var element_type = ImportType(instance.ElementType, context); var imported_instance = new GenericInstanceType(element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) { imported_arguments.Add(ImportType(arguments [i], context)); } return(imported_instance); case ElementType.Var: if (context == null || context.Type == null) { throw new InvalidOperationException(); } return(((TypeReference)context.Type).GetElementType().GenericParameters [((GenericParameter)type).Position]); case ElementType.MVar: if (context == null || context.Method == null) { throw new InvalidOperationException(); } return(context.Method.GenericParameters [((GenericParameter)type).Position]); } throw new NotSupportedException(type.etype.ToString()); }
TypeReference ImportTypeSpecification(TypeReference type, ImportGenericContext context) { switch (type.etype) { case ElementType.SzArray: var vector = (ArrayType) type; return new ArrayType (ImportType (vector.ElementType, context)); case ElementType.Ptr: var pointer = (PointerType) type; return new PointerType (ImportType (pointer.ElementType, context)); case ElementType.ByRef: var byref = (ByReferenceType) type; return new ByReferenceType (ImportType (byref.ElementType, context)); case ElementType.Pinned: var pinned = (PinnedType) type; return new PinnedType (ImportType (pinned.ElementType, context)); case ElementType.Sentinel: var sentinel = (SentinelType) type; return new SentinelType (ImportType (sentinel.ElementType, context)); case ElementType.CModOpt: var modopt = (OptionalModifierType) type; return new OptionalModifierType ( ImportType (modopt.ModifierType, context), ImportType (modopt.ElementType, context)); case ElementType.CModReqD: var modreq = (RequiredModifierType) type; return new RequiredModifierType ( ImportType (modreq.ModifierType, context), ImportType (modreq.ElementType, context)); case ElementType.Array: var array = (ArrayType) type; var imported_array = new ArrayType (ImportType (array.ElementType, context)); if (array.IsVector) return imported_array; var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear (); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions [i]; imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound)); } return imported_array; case ElementType.GenericInst: var instance = (GenericInstanceType) type; var element_type = ImportType (instance.ElementType, context); var imported_instance = new GenericInstanceType (element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) imported_arguments.Add (ImportType (arguments [i], context)); return imported_instance; case ElementType.Var: var var_parameter = (GenericParameter) type; return context.TypeParameter (type.DeclaringType.FullName, var_parameter.Position); case ElementType.MVar: var mvar_parameter = (GenericParameter) type; return context.MethodParameter (mvar_parameter.DeclaringMethod.Name, mvar_parameter.Position); case ElementType.FnPtr: var funcPtr = (FunctionPointerType)type; var imported = new FunctionPointerType() { HasThis = funcPtr.HasThis, ExplicitThis = funcPtr.ExplicitThis, CallingConvention = funcPtr.CallingConvention, ReturnType = ImportType (funcPtr.ReturnType, context) }; var parameters = funcPtr.Parameters; for (int i = 0; i < parameters.Count; i++) imported.Parameters.Add( new ParameterDefinition (ImportType (parameters [i].ParameterType, context))); return imported; } throw new NotSupportedException (type.etype.ToString ()); }
private JSForLoop ReplaceWhileLoopAndEnumerator(JSWhileLoop wl, JSExpression backingStore, JSExpression enumerator, TypeInfo enumeratorType, string arrayMember, string lengthMember) { var loopId = _NextLoopId++; var arrayVariableName = String.Format("a${0:x}", loopId); var indexVariableName = String.Format("i${0:x}", loopId); var lengthVariableName = String.Format("l${0:x}", loopId); var currentPropertyReference = enumeratorType.Definition.Properties.First((p) => p.Name == "Current"); var currentPropertyInfo = enumeratorType.Source.GetProperty(currentPropertyReference); var itemType = currentPropertyInfo.ReturnType; var arrayType = new ArrayType(itemType); var arrayVariable = new JSVariable( arrayVariableName, arrayType, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(arrayMember, arrayType)) ); var indexVariable = new JSVariable( indexVariableName, TypeSystem.Int32, Function.Method.Reference, JSLiteral.New(0) ); var lengthVariable = new JSVariable( lengthVariableName, TypeSystem.Int32, Function.Method.Reference, JSDotExpression.New(backingStore, new JSStringIdentifier(lengthMember, TypeSystem.Int32)) ); var initializer = new JSVariableDeclarationStatement( new JSBinaryOperatorExpression( JSOperator.Assignment, arrayVariable, arrayVariable.DefaultValue, arrayVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, indexVariable, indexVariable.DefaultValue, indexVariable.IdentifierType ), new JSBinaryOperatorExpression( JSOperator.Assignment, lengthVariable, lengthVariable.DefaultValue, lengthVariable.IdentifierType ) ); var condition = new JSBinaryOperatorExpression( JSBinaryOperator.LessThan, indexVariable, lengthVariable, TypeSystem.Boolean ); var increment = new JSUnaryOperatorExpression( JSUnaryOperator.PostIncrement, indexVariable, TypeSystem.Int32 ); var result = new JSForLoop( initializer, condition, new JSExpressionStatement(increment), wl.Statements.ToArray() ); result.Index = wl.Index; new PropertyAccessReplacer( enumerator, new JSProperty(currentPropertyReference, currentPropertyInfo), new JSIndexerExpression( arrayVariable, indexVariable, itemType ) ).Visit(result); return result; }
protected override bool VerifyIsConstrainedToNSObject(TypeReference type, out TypeReference constrained_type) { constrained_type = null; var gp = type as GenericParameter; if (gp != null) { if (!gp.HasConstraints) return false; foreach (var c in gp.Constraints) { if (IsNSObject (c)) { constrained_type = c; return true; } } return false; } var git = type as GenericInstanceType; if (git != null) { var rv = true; if (git.HasGenericArguments) { var newGit = new GenericInstanceType (git.ElementType); for (int i = 0; i < git.GenericArguments.Count; i++) { TypeReference constr; rv &= VerifyIsConstrainedToNSObject (git.GenericArguments [i], out constr); newGit.GenericArguments.Add (constr ?? git.GenericArguments [i]); } constrained_type = newGit; } return rv; } var el = type as ArrayType; if (el != null) { var rv = VerifyIsConstrainedToNSObject (el.ElementType, out constrained_type); if (constrained_type == null) return rv; constrained_type = new ArrayType (constrained_type, el.Rank); return rv; } var rt = type as ByReferenceType; if (rt != null) { var rv = VerifyIsConstrainedToNSObject (rt.ElementType, out constrained_type); if (constrained_type == null) return rv; constrained_type = new ByReferenceType (constrained_type); return rv; } var tr = type as PointerType; if (tr != null) { var rv = VerifyIsConstrainedToNSObject (tr.ElementType, out constrained_type); if (constrained_type == null) return rv; constrained_type = new PointerType (constrained_type); return rv; } return true; }
public TypeReference GetTypeRefFromSig(SigType t, GenericContext context) { switch (t.ElementType) { case ElementType.Class : CLASS c = t as CLASS; return GetTypeDefOrRef (c.Type, context); case ElementType.ValueType : VALUETYPE vt = t as VALUETYPE; TypeReference vtr = GetTypeDefOrRef (vt.Type, context); vtr.IsValueType = true; return vtr; case ElementType.String : return SearchCoreType (Constants.String); case ElementType.Object : return SearchCoreType (Constants.Object); case ElementType.Void : return SearchCoreType (Constants.Void); case ElementType.Boolean : return SearchCoreType (Constants.Boolean); case ElementType.Char : return SearchCoreType (Constants.Char); case ElementType.I1 : return SearchCoreType (Constants.SByte); case ElementType.U1 : return SearchCoreType (Constants.Byte); case ElementType.I2 : return SearchCoreType (Constants.Int16); case ElementType.U2 : return SearchCoreType (Constants.UInt16); case ElementType.I4 : return SearchCoreType (Constants.Int32); case ElementType.U4 : return SearchCoreType (Constants.UInt32); case ElementType.I8 : return SearchCoreType (Constants.Int64); case ElementType.U8 : return SearchCoreType (Constants.UInt64); case ElementType.R4 : return SearchCoreType (Constants.Single); case ElementType.R8 : return SearchCoreType (Constants.Double); case ElementType.I : return SearchCoreType (Constants.IntPtr); case ElementType.U : return SearchCoreType (Constants.UIntPtr); case ElementType.TypedByRef : return SearchCoreType (Constants.TypedReference); case ElementType.Array : ARRAY ary = t as ARRAY; return new ArrayType (GetTypeRefFromSig (ary.Type, context), ary.Shape); case ElementType.SzArray : SZARRAY szary = t as SZARRAY; ArrayType at = new ArrayType (GetTypeRefFromSig (szary.Type, context)); return at; case ElementType.Ptr : PTR pointer = t as PTR; if (pointer.Void) return new PointerType (SearchCoreType (Constants.Void)); return new PointerType (GetTypeRefFromSig (pointer.PtrType, context)); case ElementType.FnPtr : FNPTR funcptr = t as FNPTR; FunctionPointerType fnptr = new FunctionPointerType (funcptr.Method.HasThis, funcptr.Method.ExplicitThis, funcptr.Method.MethCallConv, GetMethodReturnType (funcptr.Method, context)); for (int i = 0; i < funcptr.Method.ParamCount; i++) { Param p = funcptr.Method.Parameters [i]; fnptr.Parameters.Add (BuildParameterDefinition (i, p, context)); } CreateSentinelIfNeeded (fnptr, funcptr.Method); return fnptr; case ElementType.Var: VAR var = t as VAR; context.CheckProvider (context.Type, var.Index + 1); if (context.Type is GenericInstanceType) return (context.Type as GenericInstanceType).GenericArguments [var.Index]; else return context.Type.GenericParameters [var.Index]; case ElementType.MVar: MVAR mvar = t as MVAR; context.CheckProvider (context.Method, mvar.Index + 1); if (context.Method is GenericInstanceMethod) return (context.Method as GenericInstanceMethod).GenericArguments [mvar.Index]; else return context.Method.GenericParameters [mvar.Index]; case ElementType.GenericInst: GENERICINST ginst = t as GENERICINST; GenericInstanceType instance = new GenericInstanceType (GetTypeDefOrRef (ginst.Type, context)); instance.IsValueType = ginst.ValueType; context.CheckProvider (instance.GetOriginalType (), ginst.Signature.Arity); for (int i = 0; i < ginst.Signature.Arity; i++) instance.GenericArguments.Add (GetGenericArg ( ginst.Signature.Types [i], context)); return instance; default: break; } return null; }
TypeReference ImportTypeSpecification (TypeReference type, IGenericContext context) { switch (type.etype) { case ElementType.SzArray: var vector = (ArrayType) type; return new ArrayType (ImportType (vector.ElementType, context)); case ElementType.Ptr: var pointer = (PointerType) type; return new PointerType (ImportType (pointer.ElementType, context)); case ElementType.ByRef: var byref = (ByReferenceType) type; return new ByReferenceType (ImportType (byref.ElementType, context)); case ElementType.Pinned: var pinned = (PinnedType) type; return new PinnedType (ImportType (pinned.ElementType, context)); case ElementType.Sentinel: var sentinel = (SentinelType) type; return new SentinelType (ImportType (sentinel.ElementType, context)); case ElementType.CModOpt: var modopt = (OptionalModifierType) type; return new OptionalModifierType ( ImportType (modopt.ModifierType, context), ImportType (modopt.ElementType, context)); case ElementType.CModReqD: var modreq = (RequiredModifierType) type; return new RequiredModifierType ( ImportType (modreq.ModifierType, context), ImportType (modreq.ElementType, context)); case ElementType.Array: var array = (ArrayType) type; var imported_array = new ArrayType (ImportType (array.ElementType, context)); if (array.IsVector) return imported_array; var dimensions = array.Dimensions; var imported_dimensions = imported_array.Dimensions; imported_dimensions.Clear (); for (int i = 0; i < dimensions.Count; i++) { var dimension = dimensions [i]; imported_dimensions.Add (new ArrayDimension (dimension.LowerBound, dimension.UpperBound)); } return imported_array; case ElementType.GenericInst: var instance = (GenericInstanceType) type; var element_type = ImportType (instance.ElementType, context); var imported_instance = new GenericInstanceType (element_type); var arguments = instance.GenericArguments; var imported_arguments = imported_instance.GenericArguments; for (int i = 0; i < arguments.Count; i++) imported_arguments.Add (ImportType (arguments [i], context)); return imported_instance; case ElementType.Var: if (context == null || context.Type == null) throw new InvalidOperationException (); return ((TypeReference) context.Type).GetElementType ().GenericParameters [((GenericParameter) type).Position]; case ElementType.MVar: if (context == null || context.Method == null) throw new InvalidOperationException (); return context.Method.GenericParameters [((GenericParameter) type).Position]; } throw new NotSupportedException (type.etype.ToString ()); }
static TypeReference ImportType(TypeReference typeRef, ModuleDefinition mod, MethodReference context, Dictionary<MetadataToken, IMemberDefinition> mems) { TypeReference ret = typeRef; if (typeRef is TypeSpecification) { if (typeRef is ArrayType) { ArrayType _spec = typeRef as ArrayType; ret = new ArrayType(ImportType(_spec.ElementType, mod, context, mems)); (ret as ArrayType).Dimensions.Clear(); foreach (var i in _spec.Dimensions) (ret as ArrayType).Dimensions.Add(i); } else if (typeRef is GenericInstanceType) { GenericInstanceType _spec = typeRef as GenericInstanceType; ret = new GenericInstanceType(ImportType(_spec.ElementType, mod, context, mems)); foreach (var i in _spec.GenericArguments) (ret as GenericInstanceType).GenericArguments.Add(ImportType(i, mod, context, mems)); } else if (typeRef is OptionalModifierType) { ret = new OptionalModifierType(ImportType((typeRef as OptionalModifierType).ModifierType, mod, context, mems), ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is RequiredModifierType) { ret = new RequiredModifierType(ImportType((typeRef as RequiredModifierType).ModifierType, mod, context, mems), ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); } else if (typeRef is ByReferenceType) ret = new ByReferenceType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); else if (typeRef is PointerType) ret = new PointerType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); else if (typeRef is PinnedType) ret = new PinnedType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); else if (typeRef is SentinelType) ret = new SentinelType(ImportType((typeRef as TypeSpecification).ElementType, mod, context, mems)); else throw new NotSupportedException(); } else if (typeRef is GenericParameter) { if (context == null || (typeRef as GenericParameter).Owner is TypeReference || (typeRef as GenericParameter).Position >= context.GenericParameters.Count) return typeRef; return context.GenericParameters[(typeRef as GenericParameter).Position]; } else { if (mems != null && mems.ContainsKey(typeRef.MetadataToken)) ret = mems[typeRef.MetadataToken] as TypeReference; else if (!(ret is TypeDefinition) && typeRef.Scope.Name != "Confuser.Core.Injections.dll") ret = mod.Import(ret); } return ret; }
void doArrayType(ArrayType arrayType) { bool present; if (arrayTypes.TryGetValue(arrayType, out present)) return; arrayTypes[arrayType] = true; addArrayType(arrayType); }
public ArrayDimensionCollection(ArrayType container) { m_container = container; }
public static TypeReference ChangeGenericParameters(this TypeReference type, IEnumerable<GenericParameter> genericParameters) { if (type.GenericParameters == genericParameters) return type; TypeReference result; var arrayType = type as ArrayType; if (arrayType != null) { result = new ArrayType(arrayType.ElementType, arrayType.Rank); } else { var genericInstanceType = type as GenericInstanceType; if (genericInstanceType != null) { result = new GenericInstanceType(genericInstanceType.ElementType); } else if (type.GetType() == typeof(TypeReference)) { result = new TypeReference(type.Namespace, type.Name, type.Module, type.Scope, type.IsValueType); } else { throw new NotSupportedException(); } } SetGenericParameters(result, genericParameters); return result; }
protected MethodReference GetMethod(TypeReference typeRef, string methodName, List<TypeReference> args = null, int arrayCount = 0, ModuleDefinition moduleDefinition = null) { if (arrayCount > 0) { ArrayType arrayType = new ArrayType(typeRef, arrayCount); TypeReference arrayTypeRef = moduleDefinition.Import(new ArrayType(typeRef, arrayCount)); return new MethodReference("Get", typeRef, arrayTypeRef); } else { if (args != null) { return typeRef.Resolve().Methods.Single(m => m.Name == methodName && CompareParameters(m, args)); } else { return typeRef.Resolve().Methods.Single(m => m.Name == methodName); } } }
private static int RecursiveGenericDepthFor(ArrayType type, int depth) { return (depth + MaximumDepthFor(depth, type.ElementType, 0)); }
private static bool AreSame(ArrayType a, ArrayType b) => (a.Rank == b.Rank);
public static TypeReference SubstituteTypeArgs(TypeReference type, MemberReference member) { if (type is TypeSpecification) { ArrayType arrayType = type as ArrayType; if (arrayType != null) { TypeReference elementType = SubstituteTypeArgs(arrayType.ElementType, member); if (elementType != arrayType.ElementType) { ArrayType newArrayType = new ArrayType(elementType); newArrayType.Dimensions.Clear(); // remove the single dimension that Cecil adds by default foreach (ArrayDimension d in arrayType.Dimensions) newArrayType.Dimensions.Add(d); return newArrayType; } else { return type; } } ByReferenceType refType = type as ByReferenceType; if (refType != null) { TypeReference elementType = SubstituteTypeArgs(refType.ElementType, member); return elementType != refType.ElementType ? new ByReferenceType(elementType) : type; } GenericInstanceType giType = type as GenericInstanceType; if (giType != null) { GenericInstanceType newType = new GenericInstanceType(giType.ElementType); bool isChanged = false; for (int i = 0; i < giType.GenericArguments.Count; i++) { newType.GenericArguments.Add(SubstituteTypeArgs(giType.GenericArguments[i], member)); isChanged |= newType.GenericArguments[i] != giType.GenericArguments[i]; } return isChanged ? newType : type; } OptionalModifierType optmodType = type as OptionalModifierType; if (optmodType != null) { TypeReference elementType = SubstituteTypeArgs(optmodType.ElementType, member); return elementType != optmodType.ElementType ? new OptionalModifierType(optmodType.ModifierType, elementType) : type; } RequiredModifierType reqmodType = type as RequiredModifierType; if (reqmodType != null) { TypeReference elementType = SubstituteTypeArgs(reqmodType.ElementType, member); return elementType != reqmodType.ElementType ? new RequiredModifierType(reqmodType.ModifierType, elementType) : type; } PointerType ptrType = type as PointerType; if (ptrType != null) { TypeReference elementType = SubstituteTypeArgs(ptrType.ElementType, member); return elementType != ptrType.ElementType ? new PointerType(elementType) : type; } } GenericParameter gp = type as GenericParameter; if (gp != null) { if (member.DeclaringType is ArrayType) { return ((ArrayType)member.DeclaringType).ElementType; } else if (gp.Owner.GenericParameterType == GenericParameterType.Method) { return ((GenericInstanceMethod)member).GenericArguments[gp.Position]; } else { return ((GenericInstanceType)member.DeclaringType).GenericArguments[gp.Position]; } } return type; }
public void WriteTypeSignature(TypeReference type) { if (type == null) { throw new ArgumentNullException(); } ElementType etype = type.etype; switch (etype) { case ElementType.Var: case ElementType.MVar: { GenericParameter obj = (GenericParameter)type; WriteElementType(etype); int position = obj.Position; if (position == -1) { throw new NotSupportedException(); } base.WriteCompressedUInt32((uint)position); break; } case ElementType.GenericInst: { GenericInstanceType genericInstanceType = (GenericInstanceType)type; WriteElementType(ElementType.GenericInst); WriteElementType(genericInstanceType.IsValueType ? ElementType.ValueType : ElementType.Class); base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(genericInstanceType.ElementType)); WriteGenericInstanceSignature(genericInstanceType); break; } case ElementType.Ptr: case ElementType.ByRef: case ElementType.Sentinel: case ElementType.Pinned: { TypeSpecification typeSpecification = (TypeSpecification)type; WriteElementType(etype); WriteTypeSignature(typeSpecification.ElementType); break; } case ElementType.FnPtr: { FunctionPointerType method = (FunctionPointerType)type; WriteElementType(ElementType.FnPtr); WriteMethodSignature(method); break; } case ElementType.CModReqD: case ElementType.CModOpt: { IModifierType type2 = (IModifierType)type; WriteModifierSignature(etype, type2); break; } case ElementType.Array: { ArrayType arrayType = (ArrayType)type; if (!arrayType.IsVector) { WriteArrayTypeSignature(arrayType); } else { WriteElementType(ElementType.SzArray); WriteTypeSignature(arrayType.ElementType); } break; } case ElementType.None: WriteElementType(type.IsValueType ? ElementType.ValueType : ElementType.Class); base.WriteCompressedUInt32(MakeTypeDefOrRefCodedRID(type)); break; default: if (TryWriteElementType(type)) { break; } throw new NotSupportedException(); } }