示例#1
0
        /// <summary>
        /// 定义一个动态方法。
        /// </summary>
        /// <typeparam name="TDelegate">委托类型</typeparam>
        /// <param name="callback">方法生成器回调</param>
        /// <param name="restrictedSkipVisibility">是否跳过验证</param>
        /// <returns>返回一个委托</returns>
        public static TDelegate DefineDynamicMethod <TDelegate>(Action <DynamicMethod, ILGenerator> callback, bool restrictedSkipVisibility = false) where TDelegate : Delegate
        {
            MethodHelper.GetParametersTypes(typeof(TDelegate), out var parameterTypes, out var returnType);

            var dynamicMethod = new DynamicMethod(
                $"{nameof(DynamicAssembly)}_{nameof(DynamicMethod)}_{Guid.NewGuid().ToString("N")}",
                returnType,
                parameterTypes,
                restrictedSkipVisibility
                );

            callback(dynamicMethod, dynamicMethod.GetILGenerator());

            return(MethodHelper.CreateDelegate <TDelegate>(dynamicMethod));
        }
示例#2
0
        public static IEnumerable <Func <Type, object> > GetAllocateMethods()
        {
            {
                if (TypeHelper.GetTypeForAllAssembly("System.RuntimeTypeHandle")?.GetMethod("Allocate", Flags) is MethodInfo methodInfo)
                {
                    MethodHelper.GetParametersTypes(methodInfo, out var parameterTypes, out var returnType);

                    if (returnType == typeof(object) && parameterTypes.Length == 1 && parameterTypes[0].IsInstanceOfType(typeof(object)))
                    {
                        yield return(MethodHelper.CreateDelegate <Func <Type, object> >(methodInfo, false));
                    }
                }
            }

            {
                if (TypeHelper.GetTypeForAllAssembly("System.StubHelpers.StubHelpers")?.GetMethod("AllocateInternal", Flags) is MethodInfo methodInfo)
                {
                    MethodHelper.GetParametersTypes(methodInfo, out var parameterTypes, out var returnType);

                    if (returnType == typeof(object) && parameterTypes.Length == 1 && parameterTypes[0].IsInstanceOfType(typeof(object)))
                    {
                        yield return(MethodHelper.CreateDelegate <Func <Type, object> >(methodInfo, false));
                    }
                }
            }

            {
                if (TypeHelper.GetTypeForAllAssembly("System.Runtime.Remoting.Activation.ActivationServices")?.GetMethod("AllocateUninitializedClassInstance", Flags) is MethodInfo methodInfo)
                {
                    MethodHelper.GetParametersTypes(methodInfo, out var parameterTypes, out var returnType);

                    if (returnType == typeof(object) && parameterTypes.Length == 1 && parameterTypes[0].IsInstanceOfType(typeof(object)))
                    {
                        yield return(MethodHelper.CreateDelegate <Func <Type, object> >(methodInfo, false));
                    }

                    if (returnType == typeof(object) && parameterTypes.Length == 1 && parameterTypes[0] == typeof(IntPtr))
                    {
                        var internalFunc = MethodHelper.CreateDelegate <Func <IntPtr, object> >(methodInfo, false);

                        yield return((type) => internalFunc(type.TypeHandle.Value));
                    }
                }
            }
        }
示例#3
0
        private static object Clone(object obj)
        {
            if (memberwiseClone == null)
            {
                lock (typeof(TypeHelper))
                {
                    if (memberwiseClone == null)
                    {
                        var memberwiseCloneMethod = typeof(object).GetMethod(MemberwiseCloneName, BindingFlags.NonPublic | BindingFlags.Instance);
                        if (memberwiseCloneMethod != null)
                        {
                            memberwiseClone = MethodHelper.CreateDelegate <MemberwiseCloneDelegate>(memberwiseCloneMethod, SignatureLevels.Cast);
                        }
                    }
                }
            }

            return(memberwiseClone(obj));
        }
示例#4
0
 static CloneHelper()
 {
     FuncMemberwiseClone = MethodHelper.CreateDelegate <Func <object, object> >(
         typeof(object).GetMethod(nameof(MemberwiseClone), BindingFlags.NonPublic | BindingFlags.Instance),
         false);
 }
 static CloneHelper()
 {
     FuncMemberwiseClone = MethodHelper.CreateDelegate <Func <object, object> >(
         typeof(object).GetMethod("MemberwiseClone", BindingFlags.NonPublic | BindingFlags.Instance),
         SignatureLevels.Cast);
 }
示例#6
0
        /// <summary>
        /// 获取一个类型占用的内存大小。如果是 Class 则不包括 ObjectHandle 的大小。
        /// </summary>
        /// <param name="type">类型信息</param>
        /// <returns>返回内存大小。</returns>
        public unsafe static uint SizeOf(Type type)
        {
            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (type is TypeBuilder)
            {
                throw new ArgumentException("Unable get size of a TypeBuilder.", nameof(type));
            }

            if (type.IsGenericTypeDefinition)
            {
                throw new ArgumentException("Unable get size of a generic definition type.", nameof(type));
            }

            if (type.IsGenericTypeDefinition)
            {
                return(0);
            }

            switch (Type.GetTypeCode(type))
            {
            case TypeCode.Boolean:
                return(sizeof(bool));

            case TypeCode.Char:
                return(sizeof(char));

            case TypeCode.SByte:
                return(sizeof(sbyte));

            case TypeCode.Byte:
                return(sizeof(byte));

            case TypeCode.Int16:
                return(sizeof(short));

            case TypeCode.UInt16:
                return(sizeof(ushort));

            case TypeCode.Int32:
                return(sizeof(int));

            case TypeCode.UInt32:
                return(sizeof(uint));

            case TypeCode.Int64:
                return(sizeof(long));

            case TypeCode.UInt64:
                return(sizeof(ulong));

            case TypeCode.Single:
                return(sizeof(float));

            case TypeCode.Double:
                return(sizeof(double));

            case TypeCode.Decimal:
                return(sizeof(decimal));

            case TypeCode.DateTime:
                return((uint)sizeof(DateTime));
            }

            if (type.IsPointer ||
                type.IsInterface ||
                type.IsByRef ||
                typeof(object) == type ||
                typeof(IntPtr) == type)
            {
                return((uint)IntPtr.Size);
            }

            if (typeSizeCache == null)
            {
                lock (lockObject)
                {
                    if (typeSizeCache == null)
                    {
                        typeSizeCache     = new IdCache <uint>();
                        typeSizeCacheLock = new object();
                    }

                    var sizeOfHelperMethod = typeof(Marshal).GetMethod(MarshalSizeOfHelperName, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static);

                    if (sizeOfHelperMethod != null)
                    {
                        sizeOfHelper = MethodHelper.CreateDelegate <SizeOfHelperDelegate>(sizeOfHelperMethod, SignatureLevels.Cast);
                    }

                    pointerSizeOfMethod = typeof(Pointer).GetMethod(nameof(Pointer.SizeOf), Type.EmptyTypes);
                }
            }

            if (type.IsValueType)
            {
                if (sizeOfHelper != null)
                {
                    return((uint)sizeOfHelper(type, false));
                }

                try
                {
                    return((uint)Marshal.SizeOf(type));
                }
                catch (Exception)
                {
                }
            }

            var typeId = (long)type.TypeHandle.Value;

            if (typeSizeCache.TryGetValue(typeId, out uint size))
            {
                return(size);
            }

            lock (typeSizeCacheLock)
            {
                if (typeSizeCache.TryGetValue(typeId, out size))
                {
                    return(size);
                }

                if (type.IsValueType)
                {
                    size = (uint)pointerSizeOfMethod.MakeGenericMethod(type).Invoke(null, null);
                }
                else
                {
                    var fields = type.GetFields(BindingFlags.NonPublic |
                                                BindingFlags.Public |
                                                BindingFlags.Instance |
                                                BindingFlags.DeclaredOnly);

                    if (fields.Length == 0)
                    {
                        size = (uint)IntPtr.Size;
                    }
                    else
                    {
                        int right              = fields.Length - 1;
                        var maxOffset          = OffsetOf(fields[right]);
                        var maxOffsetFieldType = fields[right].FieldType;

                        while (right > 0)
                        {
                            --right;

                            var offset = OffsetOf(fields[right]);

                            if (offset > maxOffset)
                            {
                                maxOffset          = offset;
                                maxOffsetFieldType = fields[right].FieldType;
                            }
                        }

                        // = last field offset + last field size + type handle size;
                        size = maxOffset + (maxOffsetFieldType.IsValueType ? SizeOf(maxOffsetFieldType) : (uint)IntPtr.Size) + ((uint)IntPtr.Size);
                    }
                }

                typeSizeCache[typeId] = size;
            }

            return(size);
        }
示例#7
0
        private static object AllocateByInternal(Type type)
        {
            if (!allocateIsInitialized)
            {
                lock (typeof(TypeHelper))
                {
                    if (!allocateIsInitialized)
                    {
                        allocateIsInitialized = true;

                        var allocateMethod = typeof(RuntimeTypeHandle).GetMethod(AllocateMethodName, BindingFlags.NonPublic | BindingFlags.Static);
                        if (allocateMethod != null)
                        {
                            allocate = MethodHelper.CreateDelegate <AllocateDelegate>(allocateMethod, SignatureLevels.Cast);
                        }

                        var stubHelpersType = Type.GetType(StubHelpersTypeName);
                        if (stubHelpersType != null)
                        {
                            var allocateInternalMethod = stubHelpersType.GetMethod(AllocateInternalName, BindingFlags.Static | BindingFlags.NonPublic);
                            if (allocateInternalMethod != null)
                            {
                                allocateInternal = MethodHelper.CreateDelegate <AllocateInternalDelegate>(allocateInternalMethod, SignatureLevels.Cast);
                            }
                        }

                        var activationServicesType = Type.GetType(ActivationServicesTypeName);
                        if (activationServicesType != null)
                        {
                            var allocateUninitializedClassInstanceMethod = activationServicesType.GetMethod(AllocateUninitializedClassInstanceName, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
                            if (allocateUninitializedClassInstanceMethod != null)
                            {
                                allocateUninitializedClassInstance = MethodHelper.CreateDelegate <AllocateUninitializedClassInstanceDelegate>(allocateUninitializedClassInstanceMethod, SignatureLevels.Cast);
                            }
                        }
                    }
                }
            }

            if (allocate != null)
            {
                try
                {
                    return(allocate(type));
                }
                catch (Exception)
                {
                }
            }

            if (allocateInternal != null)
            {
                try
                {
                    return(allocateInternal(type.TypeHandle.Value));
                }
                catch (Exception)
                {
                }
            }

            if (allocateUninitializedClassInstance != null)
            {
                try
                {
                    return(allocateUninitializedClassInstance(type));
                }
                catch (Exception)
                {
                }
            }

            return(null);
        }