Exemple #1
0
        MemberRef ReadMethodRef(Node node)
        {
            string  name      = "";
            TypeSig declType  = null;
            TypeSig retType   = null;
            var     paramSigs = new List <TypeSig>();
            bool    instance  = false;

            for (int i = 0; i < node.Count; i++)
            {
                var child = node[i];
                if (child.Id == (int)IRConstants.STR)
                {
                    name = ((Token)child).Image;
                    name = name.Substring(1, name.Length - 2);
                }
                else if (child.Id == (int)IRConstants.INSTANCE)
                {
                    instance = true;
                }
                else if (child.Id == (int)IRConstants.METHOD_RET_TYPE)
                {
                    retType = ReadTypeRef(child[0]);
                }
                else if (child.Id == (int)IRConstants.TYPE_REF)
                {
                    declType = ReadTypeRef(child);
                }
                else if (child.Id == (int)IRConstants.METHOD_PARAMS)
                {
                    for (int j = 0; j < child.Count; j++)
                    {
                        if (child[j].Id == (int)IRConstants.TYPE_REF)
                        {
                            paramSigs.Add(ReadTypeRef(child[j]));
                        }
                    }
                }
            }

            if (instance)
            {
                return(new MemberRefUser(module, name, MethodSig.CreateInstance(retType, paramSigs.ToArray()),
                                         declType.ToTypeDefOrRef()));
            }
            return(new MemberRefUser(module, name, MethodSig.CreateStatic(retType, paramSigs.ToArray()),
                                     declType.ToTypeDefOrRef()));
        }
Exemple #2
0
        public bool restore(MethodDef method)
        {
            this.method = method;
            bool atLeastOneFailed = false;

            if (method == null || method.Body == null)
            {
                return(!atLeastOneFailed);
            }

            var instrs = method.Body.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.Operand != null)
                {
                    continue;
                }

                TypeSig operandType = null;
                switch (instr.OpCode.Code)
                {
                case Code.Ldelema:
                    var arrayType = MethodStack.getLoadedType(method, instrs, i, 1) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandType = arrayType.Next;
                    break;

                case Code.Ldobj:
                    operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 0));
                    break;

                case Code.Stobj:
                    operandType = MethodStack.getLoadedType(method, instrs, i, 0);
                    if (!isValidType(operandType))
                    {
                        operandType = getPtrElementType(MethodStack.getLoadedType(method, instrs, i, 1));
                    }
                    break;

                default:
                    continue;
                }
                if (!isValidType(operandType))
                {
                    atLeastOneFailed = true;
                    continue;
                }

                instr.Operand = operandType.ToTypeDefOrRef();
            }

            return(!atLeastOneFailed);
        }
Exemple #3
0
        internal bool RegisterGeneric(TypeSig t)
        {
            Debug.Assert(t != null, $"{nameof(t)} != null");

            // This is a temporary fix.
            // Type visibility should be handled in a much better way which would involved some analysis.
            var typeDef = t.ToTypeDefOrRef().ResolveTypeDef();

            if (typeDef != null && !typeDef.IsVisibleOutside())
            {
                return(false);
            }

            // Get proper type.
            t = SignatureUtils.GetLeaf(t);

            // scrambling voids leads to peverify errors, better leave them out.
            if (t.ElementType == ElementType.Void)
            {
                return(false);
            }

            if (!Generics.ContainsKey(t))
            {
                GenericParam newGenericParam;
                if (t.IsGenericMethodParameter)
                {
                    var mVar = t.ToGenericMVar();
                    Debug.Assert(mVar != null, $"{nameof(mVar)} != null");
                    newGenericParam = new GenericParamUser(GenericCount, mVar.GenericParam.Flags, $"T{GenericCount}")
                    {
                        Rid = mVar.Rid
                    };
                }
                else if (t.IsGenericTypeParameter)
                {
                    var tVar = t.ToGenericVar();
                    Debug.Assert(tVar != null, $"{nameof(tVar)} != null");
                    newGenericParam = new GenericParamUser(GenericCount, tVar.GenericParam.Flags, $"T{GenericCount}")
                    {
                        Rid = tVar.Rid
                    };
                }
                else
                {
                    newGenericParam = new GenericParamUser(GenericCount, GenericParamAttributes.NoSpecialConstraint, $"T{GenericCount}");
                }
                Generics.Add(t, newGenericParam);
                GenericCount++;
                _trueTypes.Add(t);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #4
0
        static bool DecodeArrayInitializer(TypeSig elementTypeRef, byte[] initialValue, ILExpression[] output)
        {
            elementTypeRef = elementTypeRef.RemovePinnedAndModifiers();
            TypeCode elementType = TypeAnalysis.GetTypeCode(elementTypeRef);

            switch (elementType)
            {
            case TypeCode.Boolean:
            case TypeCode.Byte:
                return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)d[i]));

            case TypeCode.SByte:
                return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)unchecked ((sbyte)d[i])));

            case TypeCode.Int16:
                return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)BitConverter.ToInt16(d, i)));

            case TypeCode.Char:
            case TypeCode.UInt16:
                return(DecodeArrayInitializer(initialValue, output, elementType, (d, i) => (int)BitConverter.ToUInt16(d, i)));

            case TypeCode.Int32:
            case TypeCode.UInt32:
                return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToInt32));

            case TypeCode.Int64:
            case TypeCode.UInt64:
                return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToInt64));

            case TypeCode.Single:
                return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToSingle));

            case TypeCode.Double:
                return(DecodeArrayInitializer(initialValue, output, elementType, BitConverter.ToDouble));

            case TypeCode.Object:
                var typeDef = elementTypeRef.ToTypeDefOrRef().ResolveWithinSameModule();
                if (typeDef != null && typeDef.IsEnum)
                {
                    return(DecodeArrayInitializer(typeDef.GetEnumUnderlyingType(), initialValue, output));
                }

                return(false);

            default:
                return(false);
            }
        }
Exemple #5
0
        private TypeSig RemapReference(TypeSig reference)
        {
            if (reference == null)
            {
                return(null);
            }

            var referenceTypeDefOrRef = reference.ToTypeDefOrRef();

            if (referenceTypeDefOrRef.NumberOfGenericParameters > 0)
            {
                return(RemapGenericType(reference));
            }

            return(Import(reference));
        }
Exemple #6
0
        public static bool IsEnumType(TypeSig tySig, out TypeSig enumTypeSig)
        {
            if (tySig.IsValueType)
            {
                TypeDef tyDef = tySig.ToTypeDefOrRef().ResolveTypeDef();
                if (tyDef.BaseType.FullName == "System.Enum")
                {
                    FieldDef fldDef = tyDef.Fields.FirstOrDefault(f => !f.IsStatic);
                    Debug.Assert(fldDef != null);
                    enumTypeSig = fldDef.FieldType;
                    return(true);
                }
            }

            enumTypeSig = null;
            return(false);
        }
Exemple #7
0
        object ConvertEnum <T>(TypeSig elemType, IList <CAArgument> oldList)
        {
            var ary  = ConvertArray <EnumInfo>(elemType, oldList);
            var list = new T[ary.Length];

            var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken);

            for (int i = 0; i < list.Length; i++)
            {
                if (ary[i].Value is T && sigComparer.Equals(elemType, ary[i].EnumType))
                {
                    list[i] = (T)ary[i].Value;
                }
            }

            return(new EnumInfo {
                EnumType = elemType.ToTypeDefOrRef(),
                Value = list,
                IsArray = true,
            });
        }
        public static TypeDef ToTypeDef(this TypeSig type)
        {
            TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDef();

            if (typeDef != null)
            {
                return(typeDef);
            }
            if (type.IsArray)
            {
                typeDef = type.Next.ToTypeDefOrRef().ResolveTypeDef();
            }
            if (typeDef != null)
            {
                return(typeDef);
            }
            if (type.IsGenericInstanceType)
            {
                typeDef = type.ToGenericInstSig().ToTypeDefOrRef().ResolveTypeDef();
            }
            return(typeDef);
        }
        private static IEnumerable <TypeSig> BaseTypes(TypeSig type)
        {
            TypeDef typeDef = type.ToTypeDefOrRef().ResolveTypeDefThrow();

            if (typeDef.BaseType == null)
            {
                yield break;
            }

            TypeSig baseType = type;

            do
            {
                var args = new GenericArguments();
                if (baseType.IsGenericInstanceType)
                {
                    args.PushTypeArgs(((GenericInstSig)baseType).GenericArguments);
                }
                baseType = args.Resolve(typeDef.BaseType.ToTypeSig());
                yield return(baseType);

                typeDef = typeDef.BaseType.ResolveTypeDef();
            } while (typeDef != null && typeDef.BaseType != null);
        }
Exemple #10
0
        public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax, int depth)
        {
            if (depth++ > MAX_CONVERTTYPE_DEPTH || type == null)
            {
                return;
            }
            var ts = type as TypeSpec;

            if (ts != null && !(ts.TypeSig is FnPtrSig))
            {
                WriteTo(((TypeSpec)type).TypeSig, writer, syntax, depth);
                return;
            }
            string typeFullName = type.FullName;
            string typeName     = type.Name.String;

            if (ts != null)
            {
                var fnPtrSig = ts.TypeSig as FnPtrSig;
                typeFullName = DnlibExtensions.GetFnPtrFullName(fnPtrSig);
                typeName     = DnlibExtensions.GetFnPtrName(fnPtrSig);
            }
            TypeSig typeSig = null;
            string  name    = type.DefinitionAssembly.IsCorLib() ? PrimitiveTypeName(typeFullName, type.Module, out typeSig) : null;

            if (syntax == ILNameSyntax.ShortTypeName)
            {
                if (name != null)
                {
                    WriteKeyword(writer, name, typeSig.ToTypeDefOrRef());
                }
                else
                {
                    writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type));
                }
            }
            else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null)
            {
                WriteKeyword(writer, name, typeSig.ToTypeDefOrRef());
            }
            else
            {
                if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
                {
                    writer.Write(DnlibExtensions.IsValueType(type) ? "valuetype" : "class", TextTokenType.Keyword);
                    writer.WriteSpace();
                }

                if (type.DeclaringType != null)
                {
                    type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName, depth);
                    writer.Write('/', TextTokenType.Operator);
                    writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type));
                }
                else
                {
                    if (!(type is TypeDef) && type.Scope != null && !(type is TypeSpec))
                    {
                        writer.Write('[', TextTokenType.Operator);
                        writer.Write(Escape(type.Scope.GetScopeName()), TextTokenType.ILModule);
                        writer.Write(']', TextTokenType.Operator);
                    }
                    if (ts != null || MustEscape(typeFullName))
                    {
                        writer.WriteReference(Escape(typeFullName), type, TextTokenHelper.GetTextTokenType(type));
                    }
                    else
                    {
                        WriteNamespace(writer, type.Namespace);
                        if (!string.IsNullOrEmpty(type.Namespace))
                        {
                            writer.Write('.', TextTokenType.Operator);
                        }
                        writer.WriteReference(IdentifierEscaper.Escape(type.Name), type, TextTokenHelper.GetTextTokenType(type));
                    }
                }
            }
        }
Exemple #11
0
        public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax, int depth)
        {
            if (depth++ > MAX_CONVERTTYPE_DEPTH)
            {
                return;
            }
            ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;

            if (type is PinnedSig)
            {
                ((PinnedSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.WriteSpace();
                writer.Write("pinned", TextTokenType.Keyword);
            }
            else if (type is ArraySig)
            {
                ArraySig at = (ArraySig)type;
                at.Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('[', TextTokenType.Operator);
                for (int i = 0; i < at.Rank; i++)
                {
                    if (i != 0)
                    {
                        writer.Write(',', TextTokenType.Operator);
                        writer.WriteSpace();
                    }
                    int? lower = i < at.LowerBounds.Count ? at.LowerBounds[i] : (int?)null;
                    uint?size  = i < at.Sizes.Count ? at.Sizes[i] : (uint?)null;
                    if (lower != null)
                    {
                        writer.Write(lower.ToString(), TextTokenType.Number);
                        if (size != null)
                        {
                            writer.Write("..", TextTokenType.Operator);
                            writer.Write((lower.Value + (int)size.Value - 1).ToString(), TextTokenType.Number);
                        }
                        else
                        {
                            writer.Write("...", TextTokenType.Operator);
                        }
                    }
                }
                writer.Write(']', TextTokenType.Operator);
            }
            else if (type is SZArraySig)
            {
                SZArraySig at = (SZArraySig)type;
                at.Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write("[]", TextTokenType.Operator);
            }
            else if (type is GenericSig)
            {
                if (((GenericSig)type).IsMethodVar)
                {
                    writer.Write("!!", TextTokenType.Operator);
                }
                else
                {
                    writer.Write("!", TextTokenType.Operator);
                }
                string typeName = type.TypeName;
                if (string.IsNullOrEmpty(typeName) || typeName[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
                {
                    writer.Write(((GenericSig)type).Number.ToString(), TextTokenType.Number);
                }
                else
                {
                    writer.Write(Escape(typeName), TextTokenHelper.GetTextTokenType(type));
                }
            }
            else if (type is ByRefSig)
            {
                ((ByRefSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('&', TextTokenType.Operator);
            }
            else if (type is PtrSig)
            {
                ((PtrSig)type).Next.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('*', TextTokenType.Operator);
            }
            else if (type is GenericInstSig)
            {
                ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes, depth);
                writer.Write('<', TextTokenType.Operator);
                var arguments = ((GenericInstSig)type).GenericArguments;
                for (int i = 0; i < arguments.Count; i++)
                {
                    if (i > 0)
                    {
                        writer.Write(',', TextTokenType.Operator);
                        writer.WriteSpace();
                    }
                    arguments[i].WriteTo(writer, syntaxForElementTypes, depth);
                }
                writer.Write('>', TextTokenType.Operator);
            }
            else if (type is CModOptSig)
            {
                ((ModifierSig)type).Next.WriteTo(writer, syntax, depth);
                writer.WriteSpace();
                writer.Write("modopt", TextTokenType.Keyword);
                writer.Write('(', TextTokenType.Operator);
                ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth);
                writer.Write(')', TextTokenType.Operator);
                writer.WriteSpace();
            }
            else if (type is CModReqdSig)
            {
                ((ModifierSig)type).Next.WriteTo(writer, syntax, depth);
                writer.WriteSpace();
                writer.Write("modreq", TextTokenType.Keyword);
                writer.Write('(', TextTokenType.Operator);
                ((ModifierSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName, depth);
                writer.Write(')', TextTokenType.Operator);
                writer.WriteSpace();
            }
            else if (type is TypeDefOrRefSig)
            {
                WriteTo(((TypeDefOrRefSig)type).TypeDefOrRef, writer, syntax, depth);
            }
            else if (type is FnPtrSig)
            {
                WriteTo(type.ToTypeDefOrRef(), writer, syntax, depth);
            }
            //TODO: SentinelSig
        }
Exemple #12
0
 static void AppendTypeName(StringBuilder b, TypeSig type)
 {
     type = type.RemovePinnedAndModifiers();
     if (type is null)
     {
         return;
     }
     if (type is GenericInstSig giType)
     {
         AppendTypeNameWithArguments(b, giType.GenericType is null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
         return;
     }
     if (type is ArraySigBase arrayType)
     {
         AppendTypeName(b, arrayType.Next);
         b.Append('[');
         var lowerBounds = arrayType.GetLowerBounds();
         var sizes       = arrayType.GetSizes();
         for (int i = 0; i < arrayType.Rank; i++)
         {
             if (i > 0)
             {
                 b.Append(',');
             }
             if (i < lowerBounds.Count && i < sizes.Count)
             {
                 b.Append(lowerBounds[i]);
                 b.Append(':');
                 b.Append(sizes[i] + lowerBounds[i] - 1);
             }
         }
         b.Append(']');
         return;
     }
     if (type is ByRefSig refType)
     {
         AppendTypeName(b, refType.Next);
         b.Append('@');
         return;
     }
     if (type is PtrSig ptrType)
     {
         AppendTypeName(b, ptrType.Next);
         b.Append('*');
         return;
     }
     if (type is GenericSig gp)
     {
         b.Append('`');
         if (gp.IsMethodVar)
         {
             b.Append('`');
         }
         b.Append(gp.Number);
     }
     else
     {
         var typeRef = type.ToTypeDefOrRef();
         if (typeRef.DeclaringType is not null)
         {
             AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
             b.Append('.');
             b.Append(typeRef.Name);
         }
         else
         {
             FullNameFactory.FullNameSB(type, false, null, null, null, b);
         }
     }
 }
Exemple #13
0
 private TypeSig FindHookTypeSigRaw(TypeSig originalSig) =>
 FindHookTypeDefRaw(originalSig.ToTypeDefOrRef()).ToTypeSig();
Exemple #14
0
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType == null ? null : giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            ArraySigBase arrayType = type as ArraySigBase;

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append('[');
                var lowerBounds = arrayType.GetLowerBounds();
                var sizes       = arrayType.GetSizes();
                for (int i = 0; i < arrayType.Rank; i++)
                {
                    if (i > 0)
                    {
                        b.Append(',');
                    }
                    if (i < lowerBounds.Count && i < sizes.Count)
                    {
                        b.Append(lowerBounds[i]);
                        b.Append(':');
                        b.Append(sizes[i] + lowerBounds[i] - 1);
                    }
                }
                b.Append(']');
                return;
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
                return;
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
                return;
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef = type.ToTypeDefOrRef();
                if (typeRef.DeclaringType != null)
                {
                    AppendTypeName(b, typeRef.DeclaringType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
        static void AppendTypeName(StringBuilder b, TypeSig type)
        {
            if (type == null)
            {
                // could happen when a TypeSpecification has no ElementType; e.g. function pointers in C++/CLI assemblies
                return;
            }
            if (type is GenericInstSig)
            {
                GenericInstSig giType = (GenericInstSig)type;
                AppendTypeNameWithArguments(b, giType.GenericType.TypeDefOrRef, giType.GenericArguments);
                return;
            }
            SZArraySig arrayType = type as SZArraySig;              // TODO: multi-dimensional array

            if (arrayType != null)
            {
                AppendTypeName(b, arrayType.Next);
                b.Append("[]");
            }
            ByRefSig refType = type as ByRefSig;

            if (refType != null)
            {
                AppendTypeName(b, refType.Next);
                b.Append('@');
            }
            PtrSig ptrType = type as PtrSig;

            if (ptrType != null)
            {
                AppendTypeName(b, ptrType.Next);
                b.Append('*');
            }
            GenericSig gp = type as GenericSig;

            if (gp != null)
            {
                b.Append('`');
                if (gp.IsMethodVar)
                {
                    b.Append('`');
                }
                b.Append(gp.Number);
            }
            else
            {
                var typeRef  = type.ToTypeDefOrRef();
                var declType = Decompiler.DnlibExtensions.GetDeclaringType(typeRef);
                if (declType != null)
                {
                    AppendTypeName(b, declType.ToTypeSig());
                    b.Append('.');
                    b.Append(typeRef.Name);
                }
                else
                {
                    b.Append(type.FullName);
                }
            }
        }
        public static string ParsedTypeSignatureStr(this TypeSig typeSig, bool useValueTypes = true, string context = null, bool typesOnly = false)
        {
            switch (typeSig.ElementType)
            {
            case ElementType.Object:
                return("DLL2SDK::mscorlib::System::Object");

            case ElementType.String:
                return("DLL2SDK::mscorlib::System::String");

            case ElementType.Void when useValueTypes:
                return("void");

            case ElementType.Boolean when useValueTypes:
                return("bool");

            case ElementType.Char when useValueTypes:
                return("wchar_t");

            case ElementType.I1 when useValueTypes:
                return("int8_t");

            case ElementType.U1 when useValueTypes:
                return("uint8_t");

            case ElementType.I2 when useValueTypes:
                return("int16_t");

            case ElementType.U2 when useValueTypes:
                return("uint16_t");

            case ElementType.I4 when useValueTypes:
                return("int32_t");

            case ElementType.U4 when useValueTypes:
                return("uint32_t");

            case ElementType.I8 when useValueTypes:
                return("int64_t");

            case ElementType.U8 when useValueTypes:
                return("uint64_t");

            case ElementType.R4 when useValueTypes:
                return("float");

            case ElementType.R8 when useValueTypes:
                return("double");

            case ElementType.I when useValueTypes:
                return("intptr_t");

            case ElementType.U when useValueTypes:
                return("uintptr_t");
            }

            var underlying = typeSig.GetNonNestedTypeRefScope().ResolveTypeDef();

            if (underlying?.IsEnum ?? false)
            {
                return(underlying.ParsedFullName());
            }

            if (typeSig.IsArray || typeSig.IsSZArray)
            {
                return($"DLL2SDK::Array<{typeSig.Next.ParsedReferenceTypeDefinition(context: context)}>");
            }

            if (typeSig.IsGenericParameter)
            {
                return(typeSig.ToGenericSig().GenericParam.Name.String.Parseable());
            }

            var genericCtx = new List <string>();

            if (typeSig.IsGenericInstanceType)
            {
                var gi = typeSig.ToGenericInstSig();
                genericCtx = new List <string>(gi.GenericArguments.Count);
                foreach (var t in gi.GenericArguments)
                {
                    genericCtx.Add(t.ParsedReferenceTypeDefinition(context: context));
                }
            }

            var typeDef = typeSig.TryGetTypeDef();

            if (typeDef?.HasGenericParameters ?? false)
            {
                var gi = typeDef.GenericParameters;
                genericCtx = new List <string>(gi.Count);
                foreach (var t in gi)
                {
                    genericCtx.Add(t.Name.String.Parseable());
                }
            }

            if (genericCtx.Count > 0)
            {
                var builder = new StringBuilder();
                if (!typesOnly)
                {
                    builder.Append(typeSig.ToTypeDefOrRef().ParsedFullName());
                }
                if (context == null)
                {
                    builder.Append("<");
                    builder.Append(string.Join(", ", genericCtx));
                    builder.Append(">");
                }
                else
                {
                    builder.Append(context);
                }
                return(builder.ToString());
            }

            if (typeSig.IsByRef || typeSig.IsPointer)
            {
                return($"{typeSig.Next.ParsedTypeSignatureStr(context: context)}");
            }

            return(typeSig.ToTypeDefOrRef().ParsedFullName());
        }
Exemple #17
0
        private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false)
        {
            var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();

            if (typeSig.IsPrimitive)
            {
                object value = null;
                switch (typeSig.TypeName)
                {
                case "Boolean":
                    value = reader.ReadBoolean();
                    break;

                case "Byte":
                    value = reader.ReadByte();
                    break;

                case "SByte":
                    value = reader.ReadSByte();
                    break;

                case "Int16":
                    value = reader.ReadInt16();
                    break;

                case "UInt16":
                    value = reader.ReadUInt16();
                    break;

                case "Int32":
                    value = reader.ReadInt32();
                    break;

                case "UInt32":
                    value = reader.ReadUInt32();
                    break;

                case "Int64":
                    value = reader.ReadInt64();
                    break;

                case "UInt64":
                    value = reader.ReadUInt64();
                    break;

                case "Single":
                    value = reader.ReadSingle();
                    break;

                case "Double":
                    value = reader.ReadDouble();
                    break;

                case "Char":
                    value = reader.ReadChar();
                    break;
                }
                reader.AlignStream(4);
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
                return;
            }
            if (typeSig.FullName == "System.String")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\"");
                return;
            }
            if (typeSig.FullName == "System.Object")
            {
                return;
            }
            if (typeDef.IsDelegate)
            {
                return;
            }
            if (typeSig is ArraySigBase)
            {
                if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable)
                {
                    return;
                }
                var size = reader.ReadInt32();
                sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
                sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                for (int i = 0; i < size; i++)
                {
                    sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                    DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2);
                }
                return;
            }
            if (!isRoot && typeSig is GenericInstSig genericInstSig)
            {
                if (genericInstSig.GenericArguments.Count == 1)
                {
                    var type = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow();
                    if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable)
                    {
                        return;
                    }
                    var size = reader.ReadInt32();
                    sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                    sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
                    sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                    for (int i = 0; i < size; i++)
                    {
                        sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                        DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2);
                    }
                }
                return;
            }
            if (indent != -1 && IsAssignFromUnityObject(typeDef))
            {
                var pptr = reader.ReadPPtr();
                sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
                return;
            }
            if (typeDef.IsEnum)
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}");
                return;
            }
            if (indent != -1 && !IsEngineType(typeDef) && !typeDef.IsSerializable)
            {
                return;
            }
            if (typeDef.FullName == "UnityEngine.Rect")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var rect = reader.ReadSingleArray(4);
                return;
            }
            if (typeDef.FullName == "UnityEngine.LayerMask")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var value = reader.ReadInt32();
                return;
            }
            if (typeDef.FullName == "UnityEngine.AnimationCurve")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var animationCurve = new AnimationCurve <float>(reader, reader.ReadSingle);
                return;
            }
            if (typeDef.FullName == "UnityEngine.Gradient")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                if (reader.version[0] == 5 && reader.version[1] < 5)
                {
                    reader.Position += 68;
                }
                else if (reader.version[0] == 5 && reader.version[1] < 6)
                {
                    reader.Position += 72;
                }
                else
                {
                    reader.Position += 168;
                }
                return;
            }
            if (typeDef.FullName == "UnityEngine.RectOffset")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var left   = reader.ReadSingle();
                var right  = reader.ReadSingle();
                var top    = reader.ReadSingle();
                var bottom = reader.ReadSingle();
                return;
            }
            if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO
            {
                throw new NotSupportedException();
            }
            if (typeDef.IsClass || typeDef.IsValueType)
            {
                if (name != null && indent != -1)
                {
                    sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                }
                if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
                }
                if (indent != -1 && typeDef.BaseType.FullName != "System.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
                }
                foreach (var fieldDef in typeDef.Fields)
                {
                    var access = fieldDef.Access & FieldAttributes.FieldAccessMask;
                    if (access != FieldAttributes.Public)
                    {
                        if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField")))
                        {
                            DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
                        }
                    }
                    else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0)
                    {
                        DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
                    }
                }
            }
        }
Exemple #18
0
 protected override ITypeDefOrRef ToType(TypeSig type) => type.ToTypeDefOrRef();
Exemple #19
0
 public Instructions Emit(OpCode opCode, TypeSig value)
 {
     return(Insert(Instruction.Create(opCode, value.ToTypeDefOrRef())));
 }
Exemple #20
0
        private static void DumpType(TypeSig typeSig, StringBuilder sb, AssetsFile assetsFile, string name, int indent, bool isRoot = false)
        {
            var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();
            var reader  = assetsFile.reader;

            if (typeDef.IsPrimitive)
            {
                object value = null;
                switch (typeDef.Name)
                {
                case "Boolean":
                    value = reader.ReadBoolean();
                    break;

                case "Byte":
                    value = reader.ReadByte();
                    break;

                case "SByte":
                    value = reader.ReadSByte();
                    break;

                case "Int16":
                    value = reader.ReadInt16();
                    break;

                case "UInt16":
                    value = reader.ReadUInt16();
                    break;

                case "Int32":
                    value = reader.ReadInt32();
                    break;

                case "UInt32":
                    value = reader.ReadUInt32();
                    break;

                case "Int64":
                    value = reader.ReadInt64();
                    break;

                case "UInt64":
                    value = reader.ReadUInt64();
                    break;

                case "Single":
                    value = reader.ReadSingle();
                    break;

                case "Double":
                    value = reader.ReadDouble();
                    break;
                }
                reader.AlignStream(4);
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
                return;
            }
            if (typeDef.FullName == "System.String")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\"");
                return;
            }
            if (typeDef.IsEnum)
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}");
                return;
            }
            if (typeSig is ArraySigBase)
            {
                var size = reader.ReadInt32();
                sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
                sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                for (int i = 0; i < size; i++)
                {
                    sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                    DumpType(typeDef.ToTypeSig(), sb, assetsFile, "data", indent + 2);
                }
                return;
            }
            if (!isRoot && typeSig is GenericInstSig genericInstSig)
            {
                var size = reader.ReadInt32();
                sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}Array Array");
                sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                if (genericInstSig.GenericArguments.Count == 1) //vector
                {
                    for (int i = 0; i < size; i++)
                    {
                        sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                        DumpType(genericInstSig.GenericArguments[0], sb, assetsFile, "data", indent + 2);
                    }
                }
                else if (genericInstSig.GenericArguments.Count == 2) //map
                {
                    for (int i = 0; i < size; i++)
                    {
                        sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                        DumpType(genericInstSig.GenericArguments[0], sb, assetsFile, "first", indent + 2);
                        DumpType(genericInstSig.GenericArguments[1], sb, assetsFile, "second", indent + 2);
                    }
                }
                return;
            }
            if (indent != -1 && typeDef.FullName == "UnityEngine.Object")
            {
                var pptr = assetsFile.ReadPPtr();
                sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
                return;
            }
            if (indent != -1 && typeDef.BaseType != null && typeDef.BaseType.FullName != "System.Object")
            {
                var flag = false;
                var type = typeDef;
                while (true)
                {
                    if (type.BaseType.FullName == "UnityEngine.Object")
                    {
                        flag = true;
                        break;
                    }
                    type = type.BaseType.ResolveTypeDefThrow();
                    if (type.BaseType == null)
                    {
                        break;
                    }
                }
                if (flag)
                {
                    var pptr = assetsFile.ReadPPtr();
                    sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
                    return;
                }
            }
            if (typeDef.IsClass || typeDef.IsValueType)
            {
                if (name != null && indent != -1)
                {
                    sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                }
                if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, assetsFile, null, indent, true);
                }
                if (indent != -1 && typeDef.BaseType.FullName != "System.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, assetsFile, null, indent, true);
                }

                /*if (typeDef.FullName == "UnityEngine.AnimationCurve") //TODO
                 * {
                 *  var AnimationCurve = new AnimationCurve<float>(reader, reader.ReadSingle, assetsFile.version);
                 * }*/
                foreach (var fieldDef in typeDef.Fields)
                {
                    var access = fieldDef.Access & FieldAttributes.FieldAccessMask;
                    if (access != FieldAttributes.Public)
                    {
                        if (fieldDef.CustomAttributes.Any(x => x.TypeFullName.Contains("SerializeField")))
                        {
                            DumpType(fieldDef.FieldType, sb, assetsFile, fieldDef.Name, indent + 1);
                        }
                    }
                    else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0)
                    {
                        DumpType(fieldDef.FieldType, sb, assetsFile, fieldDef.Name, indent + 1);
                    }
                }
            }
        }
Exemple #21
0
        private static void DumpType(TypeSig typeSig, StringBuilder sb, ObjectReader reader, string name, int indent, bool isRoot = false, bool align = true)
        {
            var typeDef = typeSig.ToTypeDefOrRef().ResolveTypeDefThrow();

            if (typeSig.IsPrimitive)
            {
                object value = null;
                switch (typeSig.TypeName)
                {
                case "Boolean":
                    value = reader.ReadBoolean();
                    break;

                case "Byte":
                    value = reader.ReadByte();
                    break;

                case "SByte":
                    value = reader.ReadSByte();
                    break;

                case "Int16":
                    value = reader.ReadInt16();
                    break;

                case "UInt16":
                    value = reader.ReadUInt16();
                    break;

                case "Int32":
                    value = reader.ReadInt32();
                    break;

                case "UInt32":
                    value = reader.ReadUInt32();
                    break;

                case "Int64":
                    value = reader.ReadInt64();
                    break;

                case "UInt64":
                    value = reader.ReadUInt64();
                    break;

                case "Single":
                    value = reader.ReadSingle();
                    break;

                case "Double":
                    value = reader.ReadDouble();
                    break;

                case "Char":
                    value = reader.ReadChar();
                    break;
                }
                if (align)
                {
                    reader.AlignStream();
                }
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {value}");
                return;
            }
            if (typeSig.FullName == "System.String")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = \"{reader.ReadAlignedString()}\"");
                return;
            }
            if (typeSig.FullName == "System.Object")
            {
                return;
            }
            if (typeDef.IsDelegate)
            {
                return;
            }
            if (typeSig is ArraySigBase)
            {
                if (!typeDef.IsEnum && !IsBaseType(typeDef) && !IsAssignFromUnityObject(typeDef) && !IsEngineType(typeDef) && !typeDef.IsSerializable)
                {
                    return;
                }
                var size = reader.ReadInt32();
                sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                for (int i = 0; i < size; i++)
                {
                    sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                    DumpType(typeDef.ToTypeSig(), sb, reader, "data", indent + 2);
                }
                return;
            }
            if (!isRoot && typeSig is GenericInstSig genericInstSig)
            {
                if (genericInstSig.GenericArguments.Count == 1)
                {
                    var genericType = genericInstSig.GenericType.ToTypeDefOrRef().ResolveTypeDefThrow();
                    var type        = genericInstSig.GenericArguments[0].ToTypeDefOrRef().ResolveTypeDefThrow();
                    if (genericInstSig.GenericArguments[0] is ArraySigBase)
                    {
                        return;
                    }
                    if (!type.IsEnum && !IsBaseType(type) && !IsAssignFromUnityObject(type) && !IsEngineType(type) && !type.IsSerializable)
                    {
                        return;
                    }
                    sb.AppendLine($"{new string('\t', indent)}{typeSig.TypeName} {name}");
                    if (genericType.Interfaces.Any(x => x.Interface.FullName == "System.Collections.Generic.ICollection`1<T>")) //System.Collections.Generic.IEnumerable`1<T>
                    {
                        var size = reader.ReadInt32();
                        sb.AppendLine($"{new string('\t', indent + 1)}int size = {size}");
                        for (int i = 0; i < size; i++)
                        {
                            sb.AppendLine($"{new string('\t', indent + 2)}[{i}]");
                            DumpType(genericInstSig.GenericArguments[0], sb, reader, "data", indent + 2, false, false);
                        }
                        reader.AlignStream();
                    }
                    else
                    {
                        DumpType(genericType.ToTypeSig(), sb, reader, "data", indent + 1);
                    }
                }
                return;
            }
            if (indent != -1 && IsAssignFromUnityObject(typeDef))
            {
                var pptr = new PPtr <Object>(reader);
                sb.AppendLine($"{new string('\t', indent)}PPtr<{typeDef.Name}> {name} = {{fileID: {pptr.m_FileID}, pathID: {pptr.m_PathID}}}");
                return;
            }
            if (typeDef.IsEnum)
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name} = {reader.ReadUInt32()}");
                return;
            }
            if (!isRoot && !IsEngineType(typeDef) && !typeDef.IsSerializable)
            {
                return;
            }
            if (typeDef.FullName == "UnityEngine.Rect")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var prefix = new string('\t', indent + 1);
                sb.AppendLine($"{prefix}float x = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float y = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float width = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float height = {reader.ReadSingle()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.LayerMask")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}uint m_Bits = {reader.ReadUInt32()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.AnimationCurve")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}<truncated>");
                var animationCurve = new AnimationCurve <float>(reader, reader.ReadSingle);
                return;
            }
            if (typeDef.FullName == "UnityEngine.Gradient")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}<truncated>");
                if (reader.version[0] == 5 && reader.version[1] < 5)
                {
                    reader.Position += 68;
                }
                else if (reader.version[0] == 5 && reader.version[1] < 6)
                {
                    reader.Position += 72;
                }
                else
                {
                    reader.Position += 168;
                }
                return;
            }
            if (typeDef.FullName == "UnityEngine.RectOffset")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var prefix = new string('\t', indent + 1);
                sb.AppendLine($"{prefix}float left = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float right = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float top = {reader.ReadSingle()}");
                sb.AppendLine($"{prefix}float bottom = {reader.ReadSingle()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.PropertyName")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}int id = {reader.ReadInt32()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.Color32")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var prefix = new string('\t', indent + 1);
                sb.AppendLine($"{prefix}byte r = {reader.ReadByte()}");
                sb.AppendLine($"{prefix}byte g = {reader.ReadByte()}");
                sb.AppendLine($"{prefix}byte b = {reader.ReadByte()}");
                sb.AppendLine($"{prefix}byte a = {reader.ReadByte()}");
                reader.AlignStream();
                return;
            }
            if (typeDef.FullName == "UnityEngine.Vector2Int")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var prefix = new string('\t', indent + 1);
                sb.AppendLine($"{prefix}int x = {reader.ReadInt32()}");
                sb.AppendLine($"{prefix}int y = {reader.ReadInt32()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.Vector3Int")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                var prefix = new string('\t', indent + 1);
                sb.AppendLine($"{prefix}int x = {reader.ReadInt32()}");
                sb.AppendLine($"{prefix}int y = {reader.ReadInt32()}");
                sb.AppendLine($"{prefix}int z = {reader.ReadInt32()}");
                return;
            }
            if (typeDef.FullName == "UnityEngine.Bounds")
            {
                sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                sb.AppendLine($"{new string('\t', indent + 1)}<truncated>");
                new AABB(reader);
                return;
            }
            if (typeDef.FullName == "UnityEngine.GUIStyle") //TODO
            {
                throw new NotSupportedException();
            }
            if (typeDef.IsClass || typeDef.IsValueType)
            {
                if (name != null && indent != -1)
                {
                    sb.AppendLine($"{new string('\t', indent)}{typeDef.Name} {name}");
                }
                if (indent == -1 && typeDef.BaseType.FullName != "UnityEngine.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
                }
                if (indent != -1 && typeDef.BaseType.FullName != "System.Object")
                {
                    DumpType(typeDef.BaseType.ToTypeSig(), sb, reader, null, indent, true);
                }
                foreach (var fieldDef in typeDef.Fields)
                {
                    var flag   = false;
                    var access = fieldDef.Access & FieldAttributes.FieldAccessMask;
                    if (access != FieldAttributes.Public)
                    {
                        if (fieldDef.CustomAttributes.Any(x => x.TypeFullName == "UnityEngine.SerializeField"))
                        {
                            flag = true;
                        }
                    }
                    else if ((fieldDef.Attributes & FieldAttributes.Static) == 0 && (fieldDef.Attributes & FieldAttributes.InitOnly) == 0 && (fieldDef.Attributes & FieldAttributes.NotSerialized) == 0)
                    {
                        flag = true;
                    }

                    if (flag)
                    {
                        if (fieldDef.FieldType.IsGenericParameter)
                        {
                            for (var i = 0; i < typeDef.GenericParameters.Count; i++)
                            {
                                var g = typeDef.GenericParameters[i];
                                if (g.FullName == fieldDef.FieldType.FullName)
                                {
                                    var type = ((GenericInstSig)typeSig).GenericArguments[i];
                                    DumpType(type, sb, reader, fieldDef.Name, indent + 1);
                                    break;
                                }
                            }
                        }
                        else
                        {
                            DumpType(fieldDef.FieldType, sb, reader, fieldDef.Name, indent + 1);
                        }
                    }
                }
            }
        }
Exemple #22
0
        public bool Restore(MethodDef method)
        {
            this.method = method;
            bool atLeastOneFailed = false;

            if (method == null || method.Body == null)
            {
                return(!atLeastOneFailed);
            }

            var instrs = method.Body.Instructions;

            for (int i = 0; i < instrs.Count; i++)
            {
                var instr = instrs[i];
                if (instr.Operand != null)
                {
                    continue;
                }

                TypeSig    operandType = null, operandTypeTmp;
                OpCode     newOpCode = null;
                SZArraySig arrayType;
                switch (instr.OpCode.Code)
                {
                case Code.Ldelem:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandTypeTmp = arrayType.Next;
                    if (operandTypeTmp == null)
                    {
                        newOpCode = OpCodes.Ldelem_Ref;
                    }
                    else
                    {
                        switch (operandTypeTmp.ElementType)
                        {
                        case ElementType.Boolean: newOpCode = OpCodes.Ldelem_I1; break;

                        case ElementType.Char: newOpCode = OpCodes.Ldelem_U2; break;

                        case ElementType.I:  newOpCode = OpCodes.Ldelem_I; break;

                        case ElementType.I1: newOpCode = OpCodes.Ldelem_I1; break;

                        case ElementType.I2: newOpCode = OpCodes.Ldelem_I2; break;

                        case ElementType.I4: newOpCode = OpCodes.Ldelem_I4; break;

                        case ElementType.I8: newOpCode = OpCodes.Ldelem_I8; break;

                        case ElementType.U:  newOpCode = OpCodes.Ldelem_I; break;

                        case ElementType.U1: newOpCode = OpCodes.Ldelem_U1; break;

                        case ElementType.U2: newOpCode = OpCodes.Ldelem_U2; break;

                        case ElementType.U4: newOpCode = OpCodes.Ldelem_U4; break;

                        case ElementType.U8: newOpCode = OpCodes.Ldelem_I8; break;

                        case ElementType.R4: newOpCode = OpCodes.Ldelem_R4; break;

                        case ElementType.R8: newOpCode = OpCodes.Ldelem_R8; break;

                        default:             newOpCode = OpCodes.Ldelem_Ref; break;
                            //TODO: Ldelem
                        }
                    }
                    break;

                case Code.Stelem:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 2) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandTypeTmp = arrayType.Next;
                    if (operandTypeTmp == null)
                    {
                        newOpCode = OpCodes.Stelem_Ref;
                    }
                    else
                    {
                        switch (operandTypeTmp.ElementType)
                        {
                        case ElementType.U:
                        case ElementType.I:  newOpCode = OpCodes.Stelem_I; break;

                        case ElementType.Boolean:
                        case ElementType.U1:
                        case ElementType.I1: newOpCode = OpCodes.Stelem_I1; break;

                        case ElementType.Char:
                        case ElementType.U2:
                        case ElementType.I2: newOpCode = OpCodes.Stelem_I2; break;

                        case ElementType.U4:
                        case ElementType.I4: newOpCode = OpCodes.Stelem_I4; break;

                        case ElementType.U8:
                        case ElementType.I8: newOpCode = OpCodes.Stelem_I8; break;

                        case ElementType.R4: newOpCode = OpCodes.Stelem_R4; break;

                        case ElementType.R8: newOpCode = OpCodes.Stelem_R8; break;

                        default: newOpCode = OpCodes.Stelem_Ref; break;
                            //TODO: Stelem
                        }
                    }
                    break;

                case Code.Ldelema:
                    arrayType = MethodStack.GetLoadedType(method, instrs, i, 1) as SZArraySig;
                    if (arrayType == null)
                    {
                        break;
                    }
                    operandType = arrayType.Next;
                    break;

                case Code.Ldobj:
                    operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 0));
                    break;

                case Code.Stobj:
                    operandType = MethodStack.GetLoadedType(method, instrs, i, 0);
                    if (!IsValidType(operandType))
                    {
                        operandType = GetPtrElementType(MethodStack.GetLoadedType(method, instrs, i, 1));
                    }
                    break;

                default:
                    continue;
                }
                if (newOpCode == null && !IsValidType(operandType))
                {
                    atLeastOneFailed = true;
                    continue;
                }

                instr.Operand = operandType.ToTypeDefOrRef();
                if (newOpCode != null)
                {
                    instr.OpCode = newOpCode;
                }
            }

            return(!atLeastOneFailed);
        }
Exemple #23
0
 protected override ITypeDefOrRef ToType(TypeSig type)
 {
     return(type.ToTypeDefOrRef());
 }
        static TypeSig ICast/* needs a better name */ (TypeSig a, TypeSig b, ICorLibTypes ts)
        {
            if (comp.Equals(a, b))
            {
                return(a);
            }
            if (comp.Equals(a, ts.String))
            {
                return(a);
            }
            if (comp.Equals(b, ts.String))
            {
                return(b);
            }
            if (comp.Equals(a, ts.IntPtr) || comp.Equals(a, ts.UIntPtr))
            {
                return(a);
            }
            if (comp.Equals(b, ts.IntPtr) || comp.Equals(b, ts.UIntPtr))
            {
                return(b);
            }
            if (comp.Equals(a, ts.Double))
            {
                return(a);
            }
            if (comp.Equals(b, ts.Double))
            {
                return(b);
            }
            if (comp.Equals(a, ts.Single))
            {
                return(a);
            }
            if (comp.Equals(b, ts.Single))
            {
                return(b);
            }
            if (comp.Equals(a, ts.Int64) || comp.Equals(a, ts.UInt64))
            {
                return(a);
            }
            if (comp.Equals(b, ts.Int64) || comp.Equals(b, ts.UInt64))
            {
                return(b);
            }

            if (!a.IsByRef || !b.IsByRef)
            {
                return(ts.Object);
            }

            var ad = a.ToTypeDefOrRef().ResolveTypeDefThrow();
            var bd = b.ToTypeDefOrRef().ResolveTypeDefThrow();

            if ((!ad.IsSequentialLayout || !ad.IsExplicitLayout) && (!bd.IsSequentialLayout || !bd.IsExplicitLayout))
            {
                return(ts.IntPtr);
            }

            // close enough
            return(ad.PackingSize > bd.PackingSize ? a : b);
        }
        private int ProcessMethod(MethodDef md)
        {
            List <GenInfo> toPatch = new List <GenInfo>();

            if (!md.HasGenericParameters)
            {
                return(0);
            }

            List <MethodSpec> callers = FindCallingSpecs(md);

            if (callers.Count == 0)
            {
                return(0);
            }

            Dictionary <int, TypeSig> locals = new Dictionary <int, TypeSig>();

            for (int i = 0; i < callers.Count; i++)
            {
                MethodSpec spec = callers[i];

                for (int x = 0; x < md.Body.Variables.Count; x++)
                {
                    Local l = md.Body.Variables[x];

                    if (!l.Type.IsGenericMethodParameter)
                    {
                        continue;
                    }
                    if (!(l.Type is GenericSig))
                    {
                        continue;
                    }


                    GenericSig gSig = l.Type as GenericSig;

                    GenericParam gParam = md.GenericParameters.Where(y => y.Number == gSig.Number).FirstOrDefault();

                    int indexOf = md.GenericParameters.IndexOf(gParam);

                    if (gSig.Number > spec.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0)
                    {
                        continue;
                    }

                    TypeSig tSig = spec.GenericInstMethodSig.GenericArguments[(int)gSig.Number];



                    ITypeDefOrRef c**t = tSig.ToTypeDefOrRef();

                    ITypeDefOrRef tRef = c**t.ScopeType;

                    if (tSig.IsSZArray)
                    {
                    }
                    l.Type = tRef.ToTypeSig();

                    if (locals.ContainsKey(l.Index))
                    {
                        if (locals[l.Index] == tRef.ToTypeSig())
                        {
                            continue;
                        }
                        else
                        {
                            locals[l.Index] = tRef.ToTypeSig();
                        }
                    }
                    else
                    {
                        locals.Add(l.Index, tRef.ToTypeSig());
                    }

                    //md.GenericParameters.Remove(gParam);
                }
            }

            if (locals.Count == 0)
            {
                return(0);
            }


            Dictionary <int, Local> newLocals = new Dictionary <int, Local>();

            foreach (var pair in locals)
            {
                int     index = pair.Key;
                TypeSig tSig  = pair.Value;

                Local newLocal = new Local(tSig);
                //newLocal.Name = "TESTING!!!" + Guid.NewGuid().ToString();
                newLocal.Index = index;

                newLocals.Add(index, newLocal);
            }

            for (int i = 0; i < md.Body.Instructions.Count; i++)
            {
                Instruction inst = md.Body.Instructions[i];
                if (inst.OpCode == OpCodes.Stloc || inst.OpCode == OpCodes.Ldloc)
                {
                    Local l = inst.Operand as Local;
                    if (newLocals.ContainsKey(l.Index))
                    {
                        md.Body.Instructions[i].Operand = newLocals[l.Index];
                    }
                }
            }

            md.Body.Variables.Clear();
            foreach (var pair in newLocals)
            {
                md.Body.Variables.Add(pair.Value);
            }

            // New local is not added at all, it is simply f****d.

            if (md.Name == "")
            {
            }

            /*for (int i = 0; i < md.Body.Variables.Count; i++)
             * {
             *  Local l = md.Body.Variables[i];
             *
             *  if (!l.Type.IsGenericMethodParameter)
             *  {
             *      continue;
             *  }
             *  if (!(l.Type is GenericSig))
             *  {
             *      continue;
             *  }
             *
             *  if (locals.ContainsKey(l))
             *  {
             *      md.Body.Variables[i].Type = locals[l];
             *  }
             * }*/

            /*for (int i = 0; i < md.Body.Instructions.Count; i++)
             * {
             *  Instruction inst = md.Body.Instructions[i];
             *
             *  // If it is a generic method
             *  if (inst.Operand != null && inst.Operand is MethodSpec)
             *  {
             *      // Investigate the method body to see if all locals are outlined, use gen param count vs local count...?
             *      // If it is the same then we know that there are variables to outline. Next is trying to identify when a legitimate generic type is there...
             *      // We need to collate them into a list so we can link how many have the same generic sig types listed
             *      // (a generic should technically have several different types).
             *
             *
             *      MethodSpec mSpec = inst.Operand as MethodSpec;
             *      if (mSpec == null)
             *      {
             *          // Failsafe check
             *          continue;
             *      }
             *
             *      MethodDef mDef = mSpec.ResolveMethodDef();
             *      if (mDef == null)
             *      {
             *          Logger.Log(this, string.Format("Resolved MethodDef is null for {0}", mSpec));
             *          continue;
             *      }
             *
             *      if (mDef.Body == null)
             *      {
             *          continue;
             *      }
             *
             *      int lCount = mDef.Body.Variables.Count;
             *      int gpCount = mSpec.GenericInstMethodSig.GenericArguments.Count;
             *
             *
             *
             *      toPatch.Add(new GenInfo() { CallingInst = inst, GenCount = gpCount, LocalCount = lCount, RawMethod = mDef, TargetGeneric = mSpec,
             *          GenericArgs = mSpec.GenericInstMethodSig.GenericArguments.ToList(),
             *      CallIndex = i,
             *      ParentMethod = md});
             *
             *  }
             * }*/


            List <GenInfo> Completed = new List <GenInfo>();

            //Completed.AddRange(toPatch);

            foreach (GenInfo inf in toPatch)
            {
                // Get count of other similar generic instances
                // ... should put in a dictionary the link between the method, and numbers.
                // Let's get it working without that for now


                // get generic param from generic arg

                // Go to local, go to type, cast type to genericsig.
                // You can then get the 'number' which corresponds to the generic parameter on the raw method
                // Relate that back to the index on the locals maybe?
                bool comp = false;

                List <GenericParam> toDelete = new List <GenericParam>();
                List <Local>        toAdd    = new List <Local>();
                for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++)
                {
                    Local l = inf.RawMethod.Body.Variables[i];

                    if (!l.Type.IsGenericMethodParameter)
                    {
                        continue;
                    }
                    if (!(l.Type is GenericSig))
                    {
                        continue;
                    }

                    GenericSig gSig = l.Type as GenericSig;

                    if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1 || gSig.Number < 0)
                    {
                        continue;
                    }
                    TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number];

                    if (inf.RawMethod.Name == "method_1")
                    {
                    }
                    if (tSig.IsGenericParameter)
                    {
                    }
                    if (tSig == null)
                    {
                        continue;
                    }

                    ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Type = tSig;
                    ((MethodDef)inf.TargetGeneric.Method).Body.Variables[i].Name = "CANCER_" + Guid.NewGuid().ToString();
                    //toAdd.Add(new Local(tSig));
                }

                //toAdd.ForEach(x => ((MethodDef)inf.TargetGeneric.Method).Body.Variables.Add(x));

                /*for (int i = 0; i < inf.RawMethod.Parameters.Count; i++)
                 * {
                 *  Parameter param = inf.RawMethod.Parameters[i];
                 *
                 *  if (!param.Type.IsGenericParameter)
                 *      continue;
                 *
                 *
                 *  GenericSig gSig = param.Type.ToGenericSig();
                 *
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[(int)gSig.Number];
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  if (inf.RawMethod.Name == "method_4")
                 *  {
                 *
                 *  }
                 *  if (tSig.IsGenericParameter)
                 *      continue;
                 *  param.Type = tSig;
                 *
                 *  //toDelete.Add(inf.RawMethod.GenericParameters.Where(x => x.Number == gSig.Number).FirstOrDefault());
                 *
                 *
                 * }*/



                /*for (int i = 0; i < inf.RawMethod.GenericParameters.Count; i++)
                 * {
                 *  GenericParam gParam = inf.RawMethod.GenericParameters[i];
                 *
                 *
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments[i];
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  MethodDef mDef = inf.TargetGeneric.Method as MethodDef;
                 *
                 *  Parameter p = mDef.Parameters.Where(x => !x.IsHiddenThisParameter && x.Type.FullName == gParam.FullName).FirstOrDefault();
                 *
                 *
                 *  if (p == null)
                 *  {
                 *      continue;
                 *  }
                 *
                 *  p.Type = tSig;
                 *
                 *  toDelete.Add(gParam);
                 *
                 *
                 * }*/
                toDelete.ForEach(x => inf.RawMethod.GenericParameters.Remove(x));

                /*for (int i = 0; i < inf.RawMethod.Body.Variables.Count; i++)
                 * {
                 *  Local l = inf.RawMethod.Body.Variables[i];
                 *
                 *  if (!l.Type.IsGenericMethodParameter)
                 *  {
                 *      continue;
                 *  }
                 *  if (!(l.Type is GenericSig))
                 *  {
                 *      continue;
                 *  }
                 *
                 *  GenericSig gSig = l.Type as GenericSig;
                 *  //if (gSig.Number > inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Count - 1)
                 *  //    continue;
                 *  TypeSig tSig = inf.TargetGeneric.GenericInstMethodSig.GenericArguments.Where(
                 *      (x) =>
                 *      {
                 *          if (!x.IsGenericMethodParameter)
                 *              return false;
                 *
                 *          GenericSig gSig2 = x.ToGenericSig();
                 *          if (gSig2 == null)
                 *              return false;
                 *
                 *          return gSig2.Number == gSig.Number;
                 *          //return true;
                 *      }
                 *      ).FirstOrDefault();
                 *
                 *  if (tSig == null)
                 *      continue;
                 *
                 *  inf.RawMethod.Body.Variables[i].Type = tSig;
                 *
                 *  comp = true;
                 * }
                 *
                 * if (comp)
                 *  Completed.Add(inf);*/
            }


            return(Completed.Count);
        }
 static TypeSig GetCommonBaseClass(ModuleDef module, TypeSig a, TypeSig b)
 {
     if (DotNetUtils.IsDelegate(a) && DotNetUtils.DerivesFromDelegate(module.Find(b.ToTypeDefOrRef())))
     {
         return(b);
     }
     if (DotNetUtils.IsDelegate(b) && DotNetUtils.DerivesFromDelegate(module.Find(a.ToTypeDefOrRef())))
     {
         return(a);
     }
     return(null);               //TODO:
 }
        void ManualFixes(ModuleDefMD mod)
        {
            var UMM = mod.Find("UnityModManagerNet.UnityModManager", false);

            if (UMM != null)
            {
                mod.Types.Remove(UMM);
            }
            //Fix Base Constructor
            var UnitInteractWithObject = mod.Find("Kingmaker.UnitLogic.Commands.UnitInteractWithObject", false);

            if (UnitInteractWithObject != null)
            {
                var UnitCommand = mod.Find("Kingmaker.UnitLogic.Commands.Base.UnitCommand", false);
                var baseCtor    = UnitCommand.FindMethod(".ctor");
                var ctor        = UnitInteractWithObject.FindMethod(".ctor");
                ReplaceBody(ctor.Body, new List <Instruction>()
                {
                    OpCodes.Ldarg_0.ToInstruction(),
                    OpCodes.Ldc_I4_1.ToInstruction(),
                    OpCodes.Ldnull.ToInstruction(),
                    OpCodes.Call.ToInstruction(baseCtor),
                    OpCodes.Ret.ToInstruction()
                });
            }
            //Remove type
            var ExampleSelectable = mod.Find("UnityEngine.UI.Extensions.ExampleSelectable", false);

            if (ExampleSelectable != null)
            {
                mod.Types.Remove(ExampleSelectable);
            }
            //Remove override property
            var QuickGraphQueue = mod.Find("QuickGraph.Collections.Queue`1", false);

            if (QuickGraphQueue != null)
            {
                var method = QuickGraphQueue.FindMethod("QuickGraph.Collections.IQueue.get_Count");
                QuickGraphQueue.Methods.Remove(method);
            }

            /* Remove block from QuickGraph.Collections
             * Comparer<TKey> @default = Comparer<TKey>.Default;
             *   this._002Ector(maximumErrorRate, keyMaxValue, (Func<TKey, TKey, int>)@default.Compare);
             */
            var BidirectionAdapterGraph = mod.Find("QuickGraph.BidirectionAdapterGraph`2", false);

            if (BidirectionAdapterGraph != null)
            {
                ClearMethod(BidirectionAdapterGraph.FindMethod(".ctor"));
            }
            var BinaryHeap = mod.Find("QuickGraph.Collections.BinaryHeap`2", false);

            if (BinaryHeap != null)
            {
                ClearMethod(BinaryHeap.FindMethod(".ctor"));
            }
            var FibonacciHeap = mod.Find("QuickGraph.Collections.FibonacciHeap`2", false);

            if (FibonacciHeap != null)
            {
                foreach (var ctor in FibonacciHeap.Methods.Where(m => m.Name == ".ctor"))
                {
                    ClearMethod(ctor);
                }
            }
            var FibonacciQueue = mod.Find("QuickGraph.Collections.FibonacciQueue`2", false);

            if (FibonacciQueue != null)
            {
                foreach (var ctor in FibonacciQueue.Methods.Where(m => m.Name == ".ctor"))
                {
                    ClearMethod(ctor);
                }
            }
            var BinaryQueue = mod.Find("QuickGraph.Collections.BinaryQueue`2", false);

            if (BinaryQueue != null)
            {
                ClearMethod(BinaryQueue.FindMethod(".ctor"));
            }
            var SoftHeap = mod.Find("QuickGraph.Collections.SoftHeap`2", false);

            if (SoftHeap != null)
            {
                ClearMethod(SoftHeap.FindMethod(".ctor"));
            }
            foreach (var type in mod.Types.ToArray())
            {
                if (type.Namespace == "ProBuilder2.Examples")
                {
                    mod.Types.Remove(type);
                }
            }
            //Positional Arguments
            var CameraController = mod.Find("Kingmaker.Controllers.Rest.CameraController", false);

            if (CameraController != null)
            {
                CameraController.Remove(CameraController.FindMethod(".ctor"));
            }
            var KingdomCameraController = mod.Find("Kingmaker.Controllers.KingdomCameraController", false);

            if (KingdomCameraController != null)
            {
                KingdomCameraController.Remove(KingdomCameraController.FindMethod(".ctor"));
            }
            //Clear cctor
            var DefaultJsonSettings = mod.Find("Kingmaker.EntitySystem.Persistence.JsonUtility.DefaultJsonSettings", false);

            if (DefaultJsonSettings != null)
            {
                ClearMethod(DefaultJsonSettings.FindMethod(".cctor"));
            }
            //Change UnitPartVisualChanges.SourceBone from Boo.List to System.List
            var UnitPartVisualChanges = mod.Find("Kingmaker.UnitLogic.Parts.UnitPartVisualChanges", false);

            if (DefaultJsonSettings != null)
            {
                var      booList            = UnitPartVisualChanges.FindField("SourceBone");
                Importer importer           = new Importer(mod);
                TypeSig  listGenericInstSig = importer.ImportAsTypeSig(typeof(System.Collections.Generic.List <String>));
                booList.FieldSig = new FieldSig(listGenericInstSig);
                var ctor = UnitPartVisualChanges.FindMethod(".ctor");
                foreach (var inst in ctor.Body.Instructions.ToArray())
                {
                    if (inst.OpCode == OpCodes.Newobj && inst.Operand is MemberRef memberRef)
                    {
                        memberRef.Class = listGenericInstSig.ToTypeDefOrRef();
                    }
                }
            }
        }
Exemple #28
0
        static Instruction LoadIndirect(TypeSig type)
        {
            switch (type.GetElementType())
            {
            case ElementType.Boolean:               return(Instruction.Create(OpCodes.Ldind_I1));

            case ElementType.Char:                  return(Instruction.Create(OpCodes.Ldind_U2));

            case ElementType.I1:                    return(Instruction.Create(OpCodes.Ldind_I1));

            case ElementType.U1:                    return(Instruction.Create(OpCodes.Ldind_U1));

            case ElementType.I2:                    return(Instruction.Create(OpCodes.Ldind_I2));

            case ElementType.U2:                    return(Instruction.Create(OpCodes.Ldind_U2));

            case ElementType.I4:                    return(Instruction.Create(OpCodes.Ldind_I4));

            case ElementType.U4:                    return(Instruction.Create(OpCodes.Ldind_U4));

            case ElementType.I8:                    return(Instruction.Create(OpCodes.Ldind_I8));

            case ElementType.U8:                    return(Instruction.Create(OpCodes.Ldind_I8));

            case ElementType.R4:                    return(Instruction.Create(OpCodes.Ldind_R4));

            case ElementType.R8:                    return(Instruction.Create(OpCodes.Ldind_R8));

            case ElementType.String:                return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.I:                             return(Instruction.Create(OpCodes.Ldind_I));

            case ElementType.U:                             return(Instruction.Create(OpCodes.Ldind_I));

            case ElementType.ValueType:             return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef()));

            case ElementType.Class:                 return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.Array:                 return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.Object:                return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.SZArray:               return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.Ptr:                   return(Instruction.Create(OpCodes.Ldind_I));

            case ElementType.FnPtr:                 return(Instruction.Create(OpCodes.Ldind_I));

            case ElementType.Var:                   return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef()));

            case ElementType.MVar:                  return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef()));

            case ElementType.TypedByRef:    return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef()));

            case ElementType.GenericInst:
                var gis = type as GenericInstSig;
                if (gis.GenericType.IsValueTypeSig)
                {
                    return(Instruction.Create(OpCodes.Ldobj, type.ToTypeDefOrRef()));
                }
                return(Instruction.Create(OpCodes.Ldind_Ref));

            case ElementType.End:
            case ElementType.Void:
            case ElementType.ByRef:
            case ElementType.ValueArray:
            case ElementType.R:
            case ElementType.CModReqd:
            case ElementType.CModOpt:
            case ElementType.Internal:
            case ElementType.Module:
            case ElementType.Sentinel:
            case ElementType.Pinned:
            default:
                return(Instruction.Create(OpCodes.Nop));
            }
        }
Exemple #29
0
        /// <summary>
        /// Relocates the <see cref="TypeSig"/>.
        /// </summary>
        /// <param name="typeSig">The type sig.</param>
        /// <returns>A new type if it was relocated, null otherwise</returns>
        /// <exception cref="InvalidOperationException">If signature is of unknown type.</exception>
        public virtual TypeSig TryRelocateTypeSig(TypeSig typeSig)
        {
            if (typeSig == null)
            {
                return(null);
            }

            if (typeSig is CorLibTypeSig corLibTypeSig)
            {
                return(TryRelocateCorLibTypeSig(corLibTypeSig));
            }

            if (typeSig is GenericInstSig genericInstSig)
            {
                return(TryRelocateGeneric(genericInstSig));
            }

            //if (typeSig is PtrSig)
            //    return null;

            if (typeSig is ByRefSig byRefSig)
            {
                return(TryRelocateByRef(byRefSig));
            }

            if (typeSig is ArraySig arraySig)
            {
                return(TryRelocateArray(arraySig));
            }

            if (typeSig is SZArraySig szArraySig)
            {
                return(TryRelocateSZArray(szArraySig));
            }

            if (typeSig is GenericVar)
            {
                return(null); // TODO constraints
            }
            if (typeSig is GenericMVar)
            {
                return(null); // TODO constraints
            }
            if (typeSig is ClassOrValueTypeSig)
            {
                var typeRef      = typeSig.TryGetTypeRef();
                var typeDefOrRef = typeRef != null?TryRelocateTypeRef(typeRef) : TryRelocateTypeDefOrRef(typeSig.ToTypeDefOrRef());

                if (typeDefOrRef == null)
                {
                    return(null);
                }
                if (typeSig is ValueTypeSig)
                {
                    return(new ValueTypeSig(typeDefOrRef));
                }
                return(typeDefOrRef.ToTypeSig());
            }

            if (typeSig is CModOptSig cModOptSig)
            {
                var next     = TryRelocateTypeSig(cModOptSig.Next);
                var modifier = TryRelocateTypeDefOrRef(cModOptSig.Modifier);
                if (next == null && modifier == null)
                {
                    return(null);
                }
                return(new CModOptSig(modifier ?? cModOptSig.Modifier, next ?? cModOptSig.Next));
            }

            if (typeSig is CModReqdSig cModReqdSig)
            {
                var next     = TryRelocateTypeSig(cModReqdSig.Next);
                var modifier = TryRelocateTypeDefOrRef(cModReqdSig.Modifier);
                if (next == null && modifier == null)
                {
                    return(null);
                }
                return(new CModReqdSig(modifier ?? cModReqdSig.Modifier, next ?? cModReqdSig.Next));
            }

            if (typeSig is FnPtrSig)
            {
                return(null); // TODO
            }
            if (typeSig is PtrSig)
            {
                var next = TryRelocateTypeSig(typeSig.Next);
                return(next != null ? new PtrSig(next) : null);
            }

            if (typeSig is PinnedSig)
            {
                var next = TryRelocateTypeSig(typeSig.Next);
                return(next != null ? new PinnedSig(next) : null);
            }

            throw new InvalidOperationException($"type {typeSig.GetType()} not supported (MoFo)");
        }