public static string ValueToString(object value, TypeSig storageType) { var t = storageType.RemovePinnedAndModifiers(); bool addCast = t.GetElementType() == ElementType.Object; if (t is SZArraySig) addCast = t.Next.RemovePinnedAndModifiers().GetElementType() == ElementType.Object; return ValueToString(value, addCast); }
public static object GetDefaultValue(TypeSig type, bool classValueTypeIsEnum = false) { var t = type.RemovePinnedAndModifiers(); switch (t.GetElementType()) { case ElementType.Boolean:return false; case ElementType.Char: return (char)0; case ElementType.I1: return (sbyte)0; case ElementType.U1: return (byte)0; case ElementType.I2: return (short)0; case ElementType.U2: return (ushort)0; case ElementType.I4: return (int)0; case ElementType.U4: return (uint)0; case ElementType.I8: return (long)0; case ElementType.U8: return (ulong)0; case ElementType.R4: return (float)0; case ElementType.R8: return (double)0; case ElementType.Class: case ElementType.ValueType: var tdr = ((ClassOrValueTypeSig)t).TypeDefOrRef; if (tdr.IsSystemType()) break; var td = tdr.ResolveTypeDef(); if (td == null) { if (classValueTypeIsEnum) return (int)0; break; } if (!td.IsEnum) break; switch (td.GetEnumUnderlyingType().RemovePinnedAndModifiers().GetElementType()) { case ElementType.Boolean:return false; case ElementType.Char: return (char)0; case ElementType.I1: return (sbyte)0; case ElementType.U1: return (byte)0; case ElementType.I2: return (short)0; case ElementType.U2: return (ushort)0; case ElementType.I4: return (int)0; case ElementType.U4: return (uint)0; case ElementType.I8: return (long)0; case ElementType.U8: return (ulong)0; case ElementType.R4: return (float)0; case ElementType.R8: return (double)0; } break; } return null; }
public string create(TypeSig typeRef) { typeRef = typeRef.RemovePinnedAndModifiers(); if (typeRef == null) return unknownNameCreator.create(); var gis = typeRef as GenericInstSig; if (gis != null) { if (gis.FullName == "System.Nullable`1" && gis.GenericArguments.Count == 1 && gis.GenericArguments[0] != null) { typeRef = gis.GenericArguments[0]; } } string prefix = getPrefix(typeRef); var elementType = typeRef.ScopeType; if (elementType == null && isFnPtrSig(typeRef)) return fnPtrNameCreator.create(); if (isGenericParam(elementType)) return genericParamNameCreator.create(); NameCreator nc; var typeFullName = typeRef.FullName; if (typeNames.TryGetValue(typeFullName, out nc)) return nc.create(); var fullName = elementType == null ? typeRef.FullName : elementType.FullName; string shortName; var dict = prefix == "" ? fullNameToShortName : fullNameToShortNamePrefix; if (!dict.TryGetValue(fullName, out shortName)) { fullName = fullName.Replace('/', '.'); int index = fullName.LastIndexOf('.'); shortName = index > 0 ? fullName.Substring(index + 1) : fullName; index = shortName.LastIndexOf('`'); if (index > 0) shortName = shortName.Substring(0, index); } return addTypeName(typeFullName, shortName, prefix).create(); }
bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) { size = 0; ts = ts.RemovePinnedAndModifiers(); if (ts == null) { return(false); } int size2 = ts.ElementType.GetPrimitiveSize(ptrSize); if (size2 >= 0) { size = (uint)size2; return(true); } var tdrs = ts as TypeDefOrRefSig; if (tdrs == null) { return(false); } var td = tdrs.TypeDef; if (td != null) { return(TypeDef.GetClassSize(td, out size)); } var tr = tdrs.TypeRef; if (tr != null) { return(TypeDef.GetClassSize(tr.Resolve(), out size)); } return(false); }
bool WriteRefIfByRef(IDecompilerOutput output, TypeSig typeSig, ParamDef pd) { if (typeSig.RemovePinnedAndModifiers() is ByRefSig) { if (pd != null && (!pd.IsIn && pd.IsOut)) { output.Write("out", BoxedTextColor.Keyword); output.Write(" ", BoxedTextColor.Text); } else { output.Write("ref", BoxedTextColor.Keyword); output.Write(" ", BoxedTextColor.Text); } return true; } return false; }
static ConstantType GetConstantType(TypeSig type, out ITypeDefOrRef enumType) { enumType = null; var t = type.RemovePinnedAndModifiers(); switch (t.GetElementType()) { case ElementType.Boolean: return ConstantType.Boolean; case ElementType.Char: return ConstantType.Char; case ElementType.I1: return ConstantType.SByte; case ElementType.U1: return ConstantType.Byte; case ElementType.I2: return ConstantType.Int16; case ElementType.U2: return ConstantType.UInt16; case ElementType.I4: return ConstantType.Int32; case ElementType.U4: return ConstantType.UInt32; case ElementType.I8: return ConstantType.Int64; case ElementType.U8: return ConstantType.UInt64; case ElementType.R4: return ConstantType.Single; case ElementType.R8: return ConstantType.Double; case ElementType.String: return ConstantType.String; case ElementType.Object: return ConstantType.Object; case ElementType.ValueType: case ElementType.Class: var tdr = ((ClassOrValueTypeSig)t).TypeDefOrRef; if (tdr.IsSystemType()) return ConstantType.Type; enumType = tdr; return ConstantType.Enum; case ElementType.SZArray: var elemType = t.Next.RemovePinnedAndModifiers(); switch (elemType.GetElementType()) { case ElementType.Boolean: return ConstantType.BooleanArray; case ElementType.Char: return ConstantType.CharArray; case ElementType.I1: return ConstantType.SByteArray; case ElementType.U1: return ConstantType.ByteArray; case ElementType.I2: return ConstantType.Int16Array; case ElementType.U2: return ConstantType.UInt16Array; case ElementType.I4: return ConstantType.Int32Array; case ElementType.U4: return ConstantType.UInt32Array; case ElementType.I8: return ConstantType.Int64Array; case ElementType.U8: return ConstantType.UInt64Array; case ElementType.R4: return ConstantType.SingleArray; case ElementType.R8: return ConstantType.DoubleArray; case ElementType.String: return ConstantType.StringArray; case ElementType.Object: return ConstantType.ObjectArray; case ElementType.ValueType: case ElementType.Class: tdr = ((ClassOrValueTypeSig)elemType).TypeDefOrRef; if (tdr.IsSystemType()) return ConstantType.TypeArray; enumType = tdr; return ConstantType.EnumArray; } break; } Debug.Fail(string.Format("Unsupported CA named type: {0}", type)); return ConstantType.Object; }
byte[] GetData(TypeSig typeSig, int level) { if (level >= 10) return null; var retType = typeSig.RemovePinnedAndModifiers(); if (retType == null) return null; switch (retType.ElementType) { case ElementType.Void: return dataVoidReturnType; case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: return dataInt32ReturnType; case ElementType.I8: case ElementType.U8: return dataInt64ReturnType; case ElementType.R4: return dataSingleReturnType; case ElementType.R8: return dataDoubleReturnType; case ElementType.I: return dataIntPtrReturnType; case ElementType.U: case ElementType.Ptr: case ElementType.FnPtr: return dataUIntPtrReturnType; case ElementType.ValueType: var td = ((ValueTypeSig)retType).TypeDefOrRef.ResolveTypeDef(); if (td != null && td.IsEnum) { var undType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); var et = undType.GetElementType(); if ((ElementType.Boolean <= et && et <= ElementType.R8) || et == ElementType.I || et == ElementType.U) return GetData(undType, level + 1); } goto case ElementType.TypedByRef; case ElementType.TypedByRef: case ElementType.Var: case ElementType.MVar: // Need ldloca, initobj, ldloc and a local variable return null; case ElementType.GenericInst: if (((GenericInstSig)retType).GenericType is ValueTypeSig) goto case ElementType.TypedByRef; goto case ElementType.Class; case ElementType.End: case ElementType.String: case ElementType.ByRef: case ElementType.Class: case ElementType.Array: case ElementType.ValueArray: case ElementType.R: case ElementType.Object: case ElementType.SZArray: case ElementType.CModReqd: case ElementType.CModOpt: case ElementType.Internal: case ElementType.Module: case ElementType.Sentinel: case ElementType.Pinned: default: return dataRefTypeReturnType; } }
/// <summary> /// Returns the <see cref="TypeSpec"/> if it is a <see cref="TypeDefOrRefSig"/>. /// </summary> /// <param name="a">this</param> /// <returns>A <see cref="TypeSpec"/> or <c>null</c> if none found</returns> public static TypeSpec TryGetTypeSpec(this TypeSig a) { var tdr = a.RemovePinnedAndModifiers() as TypeDefOrRefSig; return(tdr == null ? null : tdr.TypeSpec); }
/// <summary> /// Returns a <see cref="ByRefSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="ByRefSig"/> or <c>null</c> if it's not a /// <see cref="ByRefSig"/></returns> public static ByRefSig ToByRefSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as ByRefSig); }
/// <summary> /// Returns a <see cref="GenericInstSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="GenericInstSig"/> or <c>null</c> if it's not a /// <see cref="GenericInstSig"/></returns> public static GenericInstSig ToGenericInstSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as GenericInstSig); }
void AddPushDefaultValue(int count, ref int index, TypeSig pushType) { pushType = pushType.RemovePinned(); switch (count > 10 ? ElementType.End : pushType.RemovePinnedAndModifiers().GetElementType()) { case ElementType.Void: break; case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_I4_0)); break; case ElementType.I8: case ElementType.U8: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_I4_0)); InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Conv_I8)); break; case ElementType.R4: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_R4)); break; case ElementType.R8: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_R8)); break; case ElementType.I: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_I4_0)); InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Conv_I)); break; case ElementType.U: case ElementType.Ptr: case ElementType.FnPtr: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldc_I4_0)); InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Conv_U)); break; case ElementType.ValueType: var td = ((ValueTypeSig)pushType).TypeDefOrRef.ResolveTypeDef(); if (td != null && td.IsEnum) { var undType = td.GetEnumUnderlyingType().RemovePinnedAndModifiers(); var et = undType.GetElementType(); if ((ElementType.Boolean <= et && et <= ElementType.R8) || et == ElementType.I || et == ElementType.U) { AddPushDefaultValue(count + 1, ref index, undType); break; } } goto case ElementType.TypedByRef; case ElementType.TypedByRef: case ElementType.Var: case ElementType.MVar: var local = new LocalVM(typeSigCreatorOptions, new LocalOptions(new Local(pushType))); this.LocalsListVM.Add(local); var newInstr = CreateInstructionVM(Code.Ldloca); newInstr.InstructionOperandVM.OperandListItem = local; InstructionsListVM.Insert(index++, newInstr); newInstr = CreateInstructionVM(Code.Initobj); newInstr.InstructionOperandVM.Other = local.Type.ToTypeDefOrRef(); InstructionsListVM.Insert(index++, newInstr); newInstr = CreateInstructionVM(Code.Ldloc); newInstr.InstructionOperandVM.OperandListItem = local; InstructionsListVM.Insert(index++, newInstr); break; case ElementType.GenericInst: if (((GenericInstSig)pushType).GenericType is ValueTypeSig) goto case ElementType.TypedByRef; goto case ElementType.Class; case ElementType.End: case ElementType.String: case ElementType.ByRef: case ElementType.Class: case ElementType.Array: case ElementType.ValueArray: case ElementType.R: case ElementType.Object: case ElementType.SZArray: case ElementType.CModReqd: case ElementType.CModOpt: case ElementType.Internal: case ElementType.Module: case ElementType.Sentinel: case ElementType.Pinned: default: InstructionsListVM.Insert(index++, CreateInstructionVM(Code.Ldnull)); break; } }
bool IsValidType(TypeSig type) { type = type.RemovePinnedAndModifiers(); if (type == null) return false; if (type.ElementType == ElementType.Void) return false; while (type != null) { switch (type.ElementType) { case ElementType.SZArray: case ElementType.Array: case ElementType.GenericInst: case ElementType.Ptr: case ElementType.Class: case ElementType.ValueType: case ElementType.FnPtr: case ElementType.Void: case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.String: case ElementType.Object: break; case ElementType.MVar: var gmvar = (GenericMVar)type; if (gmvar.Number >= method.MethodSig.GetGenParamCount()) return false; break; case ElementType.Var: var gvar = (GenericVar)type; var dt = method.DeclaringType; if (dt == null || gvar.Number >= dt.GenericParameters.Count) return false; break; case ElementType.ByRef: case ElementType.CModOpt: case ElementType.CModReqd: case ElementType.Pinned: case ElementType.Sentinel: case ElementType.ValueArray: case ElementType.R: case ElementType.End: case ElementType.Internal: case ElementType.Module: default: return false; } if (type.Next == null) break; type = type.Next; } return type != null; }
void Write(TypeSig type, ParamDef ownerParam, IList<TypeSig> typeGenArgs, IList<TypeSig> methGenArgs) { WriteRefIfByRef(type, ownerParam); var byRef = type.RemovePinnedAndModifiers() as ByRefSig; if (byRef != null) type = byRef.Next; Write(type, typeGenArgs, methGenArgs); }
/// <summary> /// Returns a <see cref="ClassSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="ClassSig"/> or <c>null</c> if it's not a /// <see cref="ClassSig"/></returns> public static ClassSig ToClassSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as ClassSig); }
bool WriteRefIfByRef(ITextOutput output, TypeSig typeSig, ParamDef pd) { if (typeSig.RemovePinnedAndModifiers() is ByRefSig) { if (pd != null && (!pd.IsIn && pd.IsOut)) { output.Write("out", TextTokenType.Keyword); output.WriteSpace(); } else { output.Write("ref", TextTokenType.Keyword); output.WriteSpace(); } return true; } return false; }
/// <summary> /// Returns a <see cref="GenericMVar"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="GenericMVar"/> or <c>null</c> if it's not a /// <see cref="GenericMVar"/></returns> public static GenericMVar ToGenericMVar(this TypeSig type) { return(type.RemovePinnedAndModifiers() as GenericMVar); }
void WriteToolTip(ITextOutput output, TypeSig type, GenericParamContext gpContext, IHasCustomAttribute typeAttributes) { var gsig = type.RemovePinnedAndModifiers() as GenericSig; var gp = GetGenericParam(gsig, gpContext); if (gp != null) { output.Write(IdentifierEscaper.Escape(gp.Name), gsig.IsMethodVar ? TextTokenType.MethodGenericParameter : TextTokenType.TypeGenericParameter); return; } WriteToolTip(output, type.ToTypeDefOrRef(), typeAttributes); }
/// <summary> /// Returns a <see cref="PtrSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="PtrSig"/> or <c>null</c> if it's not a /// <see cref="PtrSig"/></returns> public static PtrSig ToPtrSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as PtrSig); }
public static TextTokenKind GetTextTokenType(TypeSig ts) { ts = ts.RemovePinnedAndModifiers(); if (ts == null) return TextTokenKind.Text; var tdr = ts as TypeDefOrRefSig; if (tdr != null) return GetTextTokenType(tdr.TypeDefOrRef); var gsig = ts as GenericSig; if (gsig != null) return GetTextTokenType(gsig); return TextTokenKind.Text; }
/// <summary> /// Returns a <see cref="SZArraySig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="SZArraySig"/> or <c>null</c> if it's not a /// <see cref="SZArraySig"/></returns> public static SZArraySig ToSZArraySig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as SZArraySig); }
public static TypeCode GetTypeCode(TypeSig type) { if (type == null) return TypeCode.Empty; switch (type.RemovePinnedAndModifiers().GetElementType()) { case ElementType.Boolean: return TypeCode.Boolean; case ElementType.Char: return TypeCode.Char; case ElementType.I1: return TypeCode.SByte; case ElementType.U1: return TypeCode.Byte; case ElementType.I2: return TypeCode.Int16; case ElementType.U2: return TypeCode.UInt16; case ElementType.I4: return TypeCode.Int32; case ElementType.U4: return TypeCode.UInt32; case ElementType.I8: return TypeCode.Int64; case ElementType.U8: return TypeCode.UInt64; case ElementType.R4: return TypeCode.Single; case ElementType.R8: return TypeCode.Double; case ElementType.String: return TypeCode.String; default: return TypeCode.Object; } }
public static bool IsEnum(TypeSig type) { // Arrays/Pointers/ByReference resolve to their element type, but we don't want to consider those to be enums // However, GenericInstanceTypes, ModOpts etc. should be considered enums. if (type == null || IsArrayPointerOrReference(type)) return false; var typeSig = type.RemovePinnedAndModifiers(); TypeDef typeDef = typeSig.Resolve(); return typeDef != null && typeDef.IsEnum; }
TypeDef Resolve(TypeSig type) { type = type.RemovePinnedAndModifiers(); var gis = type as GenericInstSig; if (gis != null) type = gis.GenericType; var tdrs = type as TypeDefOrRefSig; if (tdrs == null) return null; var td = tdrs.TypeDef; if (td != null) return td; var tr = tdrs.TypeRef; if (tr != null) return tr.Resolve(); return null; }
static string GetPrefix(TypeSig typeRef) { string prefix = ""; typeRef = typeRef.RemovePinnedAndModifiers(); while (typeRef is PtrSig) { typeRef = typeRef.Next; prefix += "p"; } return prefix; }
/// <summary> /// Returns a <see cref="TypeDefOrRefSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="TypeDefOrRefSig"/> or <c>null</c> if it's not a /// <see cref="TypeDefOrRefSig"/></returns> public static TypeDefOrRefSig ToTypeDefOrRefSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as TypeDefOrRefSig); }
bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) { size = 0; ts = ts.RemovePinnedAndModifiers(); if (ts == null) return false; int size2 = ts.ElementType.GetPrimitiveSize(ptrSize); if (size2 >= 0) { size = (uint)size2; return true; } var tdrs = ts as TypeDefOrRefSig; if (tdrs == null) return false; var td = tdrs.TypeDef; if (td != null) return TypeDef.GetClassSize(td, out size); var tr = tdrs.TypeRef; if (tr != null) return TypeDef.GetClassSize(tr.Resolve(), out size); return false; }
/// <summary> /// Returns a <see cref="ValueTypeSig"/> /// </summary> /// <param name="type">The type</param> /// <returns>A <see cref="ValueTypeSig"/> or <c>null</c> if it's not a /// <see cref="ValueTypeSig"/></returns> public static ValueTypeSig ToValueTypeSig(this TypeSig type) { return(type.RemovePinnedAndModifiers() as ValueTypeSig); }
public static TypeDef GetType(ModuleDef module, TypeSig type) { type = type.RemovePinnedAndModifiers(); var tdr = type as TypeDefOrRefSig; if (tdr == null) return null; return GetType(module, tdr.TypeDefOrRef); }
/// <summary> /// Gets a type signature color /// </summary> /// <param name="typeSig">Type signature</param> /// <returns></returns> public virtual object GetColor(TypeSig typeSig) { typeSig = typeSig.RemovePinnedAndModifiers(); if (typeSig == null) return BoxedTextColor.Text; var tdr = typeSig as TypeDefOrRefSig; if (tdr != null) return GetColor(tdr.TypeDefOrRef); var gsig = typeSig as GenericSig; if (gsig != null) return GetColor(gsig); return BoxedTextColor.Text; }