private bool TrySetVariableType(CilVariable variable, ITypeDescriptor variableType) { if (variableType != null && variable.VariableType.FullName != variableType.FullName) { var newType = _context.TargetImage.TypeSystem.GetMscorlibType(variableType) ?? _context.ReferenceImporter.ImportTypeSignature(variableType.ToTypeSignature()); variable.VariableType = newType; // Update the expression type of all references to the variable. foreach (var use in variable.UsedBy) { use.ExpressionType = use.IsReference ? new ByReferenceTypeSignature(newType) : newType; } // Update the expected type of all expressions that are assigned to the variable. foreach (var assign in variable.AssignedBy) { assign.Value.ExpectedType = newType; } return(true); } return(false); }
public IList <CilExpression> RecompileCallArguments( IMethodDescriptor method, IList <ILExpression> arguments, VMECallOpCode opCode, ITypeDescriptor constrainedType = null) { var methodSig = method.Signature; var result = new List <CilExpression>(); // Emit arguments. for (var i = 0; i < arguments.Count; i++) { // Recompile argument. var cilArgument = (CilExpression)arguments[i].AcceptVisitor(Recompiler); // Figure out expected argument type. TypeSignature argumentType; if (methodSig.HasThis && opCode != VMECallOpCode.NEWOBJ) { // Instance method invocation. if (i == 0) { // First parameter is the object instance that this method is called on (implicit this parameter). argumentType = constrainedType?.ToTypeSignature() ?? method.DeclaringType.ToTypeSignature(); // Calls on instance methods of value types need the this parameter to be passed on by-ref. if (argumentType.IsValueType) { argumentType = new ByReferenceTypeSignature(argumentType); } } else { argumentType = methodSig.ParameterTypes[i - 1]; } } else { // Static method invocation. argumentType = methodSig.ParameterTypes[i]; } cilArgument.ExpectedType = argumentType.InstantiateGenericTypes(GenericContext); result.Add(cilArgument); } return(result); }
public IList <ITypeDescriptor> GetTypeHierarchy(ITypeDescriptor type) { var result = new List <ITypeDescriptor>(); TypeSignature typeSig; switch (type) { // The base type of an array type signature is System.Array, so it needs a special case. // Get the type hierarchy of System.Array and then append the original array type sig. case ArrayTypeSignature _: case SzArrayTypeSignature _: result.AddRange(GetTypeHierarchy(_arrayType)); result.Add(type); return(result); case ByReferenceTypeSignature byRef: result.AddRange(GetTypeHierarchy(byRef.BaseType)); // result.Add(byRef); return(result); // Type specification's Resolve method resolves the underlying element type. // We therefore need a special case here, to get the type hierarchy of the embedded signature first. case TypeSpecification typeSpec: result.AddRange(GetTypeHierarchy(typeSpec.Signature)); result.Add(typeSpec); return(result); case GenericParameterSignature genericParam: // TODO: Resolve to actual generic parameter type. result.Add(_objectType); return(result); // No type means no hierarchy. case null: return(Array.Empty <ITypeDescriptor>()); default: typeSig = type.ToTypeSignature(); break; } var genericContext = new GenericContext(null, null); while (typeSig != null) { if (typeSig is GenericInstanceTypeSignature genericInstance) { genericContext = new GenericContext(genericInstance, null); } result.Add(typeSig); var typeDef = typeSig.ToTypeDefOrRef().Resolve(); if (typeDef is null) { throw new ArgumentException( $"Could not resolve type {typeSig.FullName} in {typeSig.Scope.GetAssembly()}."); } if (typeDef.IsEnum) { typeSig = typeDef.GetEnumUnderlyingType(); } else if (typeDef.IsInterface && typeDef.BaseType is null) { typeSig = _objectType.ToTypeSignature(); } else { typeSig = typeDef.BaseType?.ToTypeSignature().InstantiateGenericTypes(genericContext); } } result.Reverse(); return(result); }
/// <summary> /// Constructs a new pointer type signature with the provided type descriptor as element type. /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <returns>The constructed by-reference type signature.</returns> public static PointerTypeSignature MakePointerType(this ITypeDescriptor type) => new PointerTypeSignature(type.ToTypeSignature());
/// <summary> /// Constructs a new pointer type signature with the provided type descriptor as element type. /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <param name="modifierType">The modifier type to add.</param> /// <param name="isRequired">Indicates whether the modifier is required or optional.</param> /// <returns>The constructed by-reference type signature.</returns> public static CustomModifierTypeSignature MakeModifierType( this ITypeDescriptor type, ITypeDefOrRef modifierType, bool isRequired) { return(new CustomModifierTypeSignature(modifierType, isRequired, type.ToTypeSignature())); }
/// <summary> /// Constructs a new pinned type signature with the provided type descriptor as element type. /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <returns>The constructed by-reference type signature.</returns> public static PinnedTypeSignature MakePinnedType(this ITypeDescriptor type) => new PinnedTypeSignature(type.ToTypeSignature());
/// <summary> /// Constructs a new by-reference type signature with the provided type descriptor as element type. /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <returns>The constructed by-reference type signature.</returns> public static ByReferenceTypeSignature MakeByReferenceType(this ITypeDescriptor type) => new ByReferenceTypeSignature(type.ToTypeSignature());
/// <summary> /// Constructs a new single-dimension, zero based array signature with the provided type descriptor /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <param name="dimensions">The dimensions of the array.</param> /// <returns>The constructed array type signature.</returns> public static ArrayTypeSignature MakeArrayType(this ITypeDescriptor type, params ArrayDimension[] dimensions) => new ArrayTypeSignature(type.ToTypeSignature(), dimensions);
/// <summary> /// Constructs a new single-dimension, zero based array signature with the provided type descriptor /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <param name="dimensionCount">The number of dimensions in the array.</param> /// <returns>The constructed array type signature.</returns> public static ArrayTypeSignature MakeArrayType(this ITypeDescriptor type, int dimensionCount) => new ArrayTypeSignature(type.ToTypeSignature(), dimensionCount);
/// <summary> /// Constructs a new single-dimension, zero based array signature with the provided type descriptor /// as element type. /// </summary> /// <param name="type">The element type.</param> /// <returns>The constructed array type signature.</returns> public static SzArrayTypeSignature MakeSzArrayType(this ITypeDescriptor type) => new SzArrayTypeSignature(type.ToTypeSignature());