Exemple #1
0
        public TypeSig GetThisTypeSig()
        {
            ClassOrValueTypeSig tySig;

            if (IsValueType)
            {
                tySig = new ValueTypeSig(Def);
            }
            else
            {
                tySig = new ClassSig(Def);
            }

            TypeSig thisSig = tySig;

            if (HasGenArgs)
            {
                thisSig = new GenericInstSig(tySig, GenArgs);
            }
            if (IsValueType)
            {
                thisSig = new ByRefSig(thisSig);
            }
            return(thisSig);
        }
Exemple #2
0
        public TypeSig GetTypeSig()
        {
            if (IsArrayType)
            {
                if (ArrayInfo.IsSZArray)
                {
                    return(new SZArraySig(GenArgs[0]));
                }

                return(new ArraySig(GenArgs[0], ArrayInfo.Rank, ArrayInfo.Sizes, ArrayInfo.LowerBounds));
            }

            if (HasGenArgs)
            {
                ClassOrValueTypeSig tySig;

                if (IsValueType)
                {
                    tySig = new ValueTypeSig(Def);
                }
                else
                {
                    tySig = new ClassSig(Def);
                }

                return(new GenericInstSig(tySig, GenArgs));
            }
            else
            {
                return(Def.ToTypeSig());
            }
        }
        public ClassOrValueTypeSig Type(bool isValueType, string ns, string name, IResolutionScope resolutionScope)
        {
            var typeRef = module.UpdateRowId(new TypeRefUser(module, ns, name, resolutionScope));
            ClassOrValueTypeSig type;

            if (isValueType)
            {
                type = new ValueTypeSig(typeRef);
            }
            else
            {
                type = new ClassSig(typeRef);
            }
            return((ClassOrValueTypeSig)Add(type));
        }
        public void InjectArray(Array arrayToInject, MethodDef method, ITypeDefOrRef arrayType, int elementSize, int instructionIndex)
        {
            var           runtimeHelpersRef     = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System.Runtime.CompilerServices", "RuntimeHelpers", method.Module.CorLibTypes.AssemblyRef));
            var           runtimeHelpersSig     = new ClassSig(runtimeHelpersRef);
            var           arrayRef              = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System", "Array", method.Module.CorLibTypes.AssemblyRef));
            var           arrayRefSig           = new ClassSig(arrayRef);
            var           runtimeFieldHandleRef = method.Module.UpdateRowId(new TypeRefUser(method.Module, "System", "RuntimeFieldHandle", method.Module.CorLibTypes.AssemblyRef));
            var           RuntimeFieldHandleSig = new ValueTypeSig(runtimeFieldHandleRef);
            var           initArraySig          = MethodSig.CreateStatic(method.Module.CorLibTypes.Void, arrayRefSig, RuntimeFieldHandleSig);
            MemberRefUser initArrayRef          = method.Module.UpdateRowId(new MemberRefUser(method.Module, "InitializeArray", initArraySig, runtimeHelpersSig.TypeDefOrRef));

            // The following will insert these instructions:
            // Ldc_I4 arraySize
            // Newarr arrayType
            // Dup
            // Ldtoken initArrayToken

            method.Body.Instructions[instructionIndex] = new Instruction(OpCodes.Call, initArrayRef);
            method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Ldtoken, Create(arrayToInject, method.Module, elementSize)));
            method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Dup));
            method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Newarr, arrayType));
            method.Body.Instructions.Insert(instructionIndex, new Instruction(OpCodes.Ldc_I4, arrayToInject.Length));
        }
Exemple #5
0
        /// <summary>
        /// Reads the next type
        /// </summary>
        /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns>
        TypeSig ReadType()
        {
            if (!recursionCounter.Increment())
            {
                return(null);
            }

            uint    num, i;
            TypeSig nextType, result = null;

            switch ((ElementType)reader.ReadByte())
            {
            case ElementType.Void:          result = corLibTypes.Void; break;

            case ElementType.Boolean:       result = corLibTypes.Boolean; break;

            case ElementType.Char:          result = corLibTypes.Char; break;

            case ElementType.I1:            result = corLibTypes.SByte; break;

            case ElementType.U1:            result = corLibTypes.Byte; break;

            case ElementType.I2:            result = corLibTypes.Int16; break;

            case ElementType.U2:            result = corLibTypes.UInt16; break;

            case ElementType.I4:            result = corLibTypes.Int32; break;

            case ElementType.U4:            result = corLibTypes.UInt32; break;

            case ElementType.I8:            result = corLibTypes.Int64; break;

            case ElementType.U8:            result = corLibTypes.UInt64; break;

            case ElementType.R4:            result = corLibTypes.Single; break;

            case ElementType.R8:            result = corLibTypes.Double; break;

            case ElementType.String:        result = corLibTypes.String; break;

            case ElementType.TypedByRef: result = corLibTypes.TypedReference; break;

            case ElementType.I:                     result = corLibTypes.IntPtr; break;

            case ElementType.U:                     result = corLibTypes.UIntPtr; break;

            case ElementType.Object:        result = corLibTypes.Object; break;

            case ElementType.Ptr:           result = new PtrSig(ReadType()); break;

            case ElementType.ByRef:         result = new ByRefSig(ReadType()); break;

            case ElementType.ValueType:     result = new ValueTypeSig(ReadTypeDefOrRef()); break;

            case ElementType.Class:         result = new ClassSig(ReadTypeDefOrRef()); break;

            case ElementType.FnPtr:         result = new FnPtrSig(ReadSig()); break;

            case ElementType.SZArray:       result = new SZArraySig(ReadType()); break;

            case ElementType.CModReqd:      result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.CModOpt:       result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break;

            case ElementType.Sentinel:      result = new SentinelSig(); break;

            case ElementType.Pinned:        result = new PinnedSig(ReadType()); break;

            case ElementType.Var:
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericVar(num, gpContext.Type);
                break;

            case ElementType.MVar:
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new GenericMVar(num, gpContext.Method);
                break;

            case ElementType.ValueArray:
                nextType = ReadType();
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ValueArraySig(nextType, num);
                break;

            case ElementType.Module:
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                result = new ModuleSig(num, ReadType());
                break;

            case ElementType.GenericInst:
                nextType = ReadType();
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num);
                var args           = genericInstSig.GenericArguments;
                for (i = 0; i < num; i++)
                {
                    args.Add(ReadType());
                }
                result = genericInstSig;
                break;

            case ElementType.Array:
                nextType = ReadType();
                uint rank;
                if (!reader.TryReadCompressedUInt32(out rank))
                {
                    break;
                }
                if (rank > MaxArrayRank)
                {
                    break;
                }
                if (rank == 0)
                {
                    result = new ArraySig(nextType, rank);
                    break;
                }
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                if (num > MaxArrayRank)
                {
                    break;
                }
                var sizes = new List <uint>((int)num);
                for (i = 0; i < num; i++)
                {
                    if (!reader.TryReadCompressedUInt32(out uint size))
                    {
                        goto exit;
                    }
                    sizes.Add(size);
                }
                if (!reader.TryReadCompressedUInt32(out num))
                {
                    break;
                }
                if (num > MaxArrayRank)
                {
                    break;
                }
                var lowerBounds = new List <int>((int)num);
                for (i = 0; i < num; i++)
                {
                    if (!reader.TryReadCompressedInt32(out int size))
                    {
                        goto exit;
                    }
                    lowerBounds.Add(size);
                }
                result = new ArraySig(nextType, rank, sizes, lowerBounds);
                break;

            case ElementType.Internal:
                IntPtr address;
                if (IntPtr.Size == 4)
                {
                    address = new IntPtr(reader.ReadInt32());
                }
                else
                {
                    address = new IntPtr(reader.ReadInt64());
                }
                result = helper.ConvertRTInternalAddress(address);
                break;

            case ElementType.End:
            case ElementType.R:
            default:
                result = null;
                break;
            }
exit:
            recursionCounter.Decrement();
            return(result);
        }
        private static void BuildStore(ModuleDef mod, ref TypeDef store)
        {
            //reused variables
            CilBody     body;
            Instruction instr;
            var         importer = new Importer(mod);

            var trType            = importer.Import(typeof(System.Type));
            var trResourceManager = importer.Import(typeof(System.Resources.ResourceManager));

            TypeSig tsType = trType.ToTypeSig();
            TypeSig tsRuntimeTypeHandle = new ValueTypeSig(importer.Import(typeof(System.RuntimeTypeHandle)));
            TypeSig tsAssembly          = importer.ImportAsTypeSig(typeof(System.Reflection.Assembly));
            TypeSig tsResourceManager   = trResourceManager.ToTypeSig();
            TypeSig tsCultureInfo       = importer.ImportAsTypeSig(typeof(System.Globalization.CultureInfo));

            //create fields

            /*
             *      .field private static class [mscorlib]System.Resources.ResourceManager resourceMan
             *      .field private static class [mscorlib]System.Globalization.CultureInfo resourceCulture
             */
            var fieldMan = new FieldDefUser("resourceMan", new FieldSig(tsResourceManager))
            {
                Attributes = FieldAttributes.Private | FieldAttributes.Static
            };

            store.Fields.Add(fieldMan);

            var fieldCulture = new FieldDefUser("resourceCulture", new FieldSig(tsCultureInfo))
            {
                Attributes = FieldAttributes.Private | FieldAttributes.Static
            };

            store.Fields.Add(fieldCulture);


            #region .ctor

            /*
             *  .method assembly hidebysig specialname rtspecialname
             *      instance void .ctor () cil managed
             *
             *  IL_0000: ldarg.0
             *      IL_0001: call      instance void [mscorlib]System.Object::.ctor()
             *      IL_0006: ret
             */

            MethodDef ctor = new MethodDefUser(".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void))
            {
                Attributes = MethodAttributes.Assembly | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
            };

            ctor.Body = body = new CilBody();
            body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
            body.Instructions.Add(OpCodes.Call.ToInstruction(new MemberRefUser(mod, ".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void), mod.CorLibTypes.Object.ToTypeDefOrRef())));
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            store.Methods.Add(ctor);
            #endregion

            #region get_ResourceManager

            /*
             *  .method public hidebysig specialname static
             *          class [mscorlib]System.Resources.ResourceManager get_ResourceManager () cil managed
             *
             *  IL_0000: ldsfld    class [mscorlib]System.Resources.ResourceManager osu_ui.ResourcesStore::resourceMan
             *          IL_0005: brtrue.s  IL_0025
             *          IL_0007: ldstr     "osu_ui.ResourcesStore"
             *          IL_000C: ldtoken   osu_ui.ResourcesStore
             *          IL_0011: call      class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
             *          IL_0016: callvirt  instance class [mscorlib]System.Reflection.Assembly [mscorlib]System.Type::get_Assembly()
             *          IL_001B: newobj    instance void [mscorlib]System.Resources.ResourceManager::.ctor(string, class [mscorlib]System.Reflection.Assembly)
             *          IL_0020: stsfld    class [mscorlib]System.Resources.ResourceManager osu_ui.ResourcesStore::resourceMan
             *          IL_0025: ldsfld    class [mscorlib]System.Resources.ResourceManager osu_ui.ResourcesStore::resourceMan
             *          IL_002A: ret
             */

            //create method
            MethodDef getMan = new MethodDefUser("get_ResourceManager", MethodSig.CreateStatic(tsResourceManager))
            {
                Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Static,
            };

            getMan.Body = body = new CilBody();
            body.Instructions.Add(OpCodes.Ldsfld.ToInstruction(fieldMan));
            body.Instructions.Add(OpCodes.Brtrue_S.ToInstruction((Instruction)null));    //add operand later
            body.Instructions.Add(OpCodes.Ldstr.ToInstruction(ResourceStoreFull));
            body.Instructions.Add(OpCodes.Ldtoken.ToInstruction((ITokenOperand)store));
            body.Instructions.Add(OpCodes.Call.ToInstruction(new MemberRefUser(mod, "GetTypeFromHandle", MethodSig.CreateStatic(tsType, tsRuntimeTypeHandle), trType)));
            body.Instructions.Add(OpCodes.Callvirt.ToInstruction(new MemberRefUser(mod, "get_Assembly", MethodSig.CreateInstance(tsAssembly), trType)));
            body.Instructions.Add(OpCodes.Newobj.ToInstruction(new MemberRefUser(mod, ".ctor", MethodSig.CreateInstance(mod.CorLibTypes.Void, mod.CorLibTypes.String, tsAssembly), trResourceManager)));
            body.Instructions.Add(OpCodes.Stsfld.ToInstruction(fieldMan));
            body.Instructions.Add(instr = OpCodes.Ldsfld.ToInstruction(fieldMan));
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            body.UpdateInstructionOffsets();
            body.Instructions[1].Operand = instr;

            store.Methods.Add(getMan);
            #endregion

            #region get_Culture

            /*
             *  .method public hidebysig specialname static
             *      class [mscorlib]System.Globalization.CultureInfo get_Culture () cil managed
             *
             *  IL_0000: ldsfld    class [mscorlib]System.Globalization.CultureInfo osu_ui.ResourcesStore::resourceCulture
             *      IL_0005: ret
             *
             */

            MethodDef getCult = new MethodDefUser("get_Culture", MethodSig.CreateStatic(tsCultureInfo))
            {
                Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Static,
            };

            getCult.Body = body = new CilBody();
            body.Instructions.Add(OpCodes.Ldsfld.ToInstruction(fieldCulture));
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            store.Methods.Add(getCult);
            #endregion

            #region get_Culture

            /*
             *  .method public hidebysig specialname static
             *      void set_Culture (class [mscorlib]System.Globalization.CultureInfo 'value') cil managed
             *
             *  IL_0000: ldarg.0
             *      IL_0001: stsfld    class [mscorlib]System.Globalization.CultureInfo osu_ui.ResourcesStore::resourceCulture
             *      IL_0006: ret
             */

            MethodDef setCult = new MethodDefUser("set_Culture", MethodSig.CreateStatic(mod.CorLibTypes.Void, tsCultureInfo))
            {
                Attributes = MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.Static,
            };
            setCult.Parameters[0].CreateParamDef();
            setCult.Parameters[0].ParamDef.Name = "value";

            setCult.Body = body = new CilBody();
            body.Instructions.Add(OpCodes.Ldarg_0.ToInstruction());
            body.Instructions.Add(OpCodes.Stsfld.ToInstruction(fieldCulture));
            body.Instructions.Add(OpCodes.Ret.ToInstruction());

            store.Methods.Add(setCult);
            #endregion
        }