Exemple #1
0
        protected Type GetConstructorTypeIntern(Type delegateType, Type targetType)
        {
            String constructorClassName = targetType.FullName + "$FastConstructor$" + delegateType.FullName;

            lock (writeLock)
            {
                AccessorClassLoader loader = AccessorClassLoader.Get(targetType);
                Type type = loader.LoadClass(constructorClassName);
                if (type != null)
                {
                    return(type);
                }
                return(CreateConstructorType(loader, constructorClassName, delegateType, targetType));
            }
        }
Exemple #2
0
        protected Type GetAccessorTypeIntern(Type targetType, IPropertyInfo property)
        {
            String accessClassName = targetType.FullName + "$" + typeof(AbstractAccessor).Name + "$" + property.Name;

            lock (writeLock)
            {
                AccessorClassLoader loader = AccessorClassLoader.Get(targetType);
                Type type = loader.LoadClass(accessClassName);
                if (type != null)
                {
                    return(type);
                }
                return(CreateType(loader, accessClassName, targetType, property));
            }
        }
Exemple #3
0
        public static AccessorClassLoader Get(Type type)
        {
            Assembly parent = type.Assembly;

            lock (writeLock)
            {
                List <KeyValuePair <Assembly, AccessorClassLoader> > toBeRemoved = null;
                foreach (KeyValuePair <Assembly, AccessorClassLoader> entry in accessClassLoaders)
                {
                    Assembly assembly = entry.Key;
                    if (assembly == null)
                    {
                        // Current ClassLoader is invalidated
                        if (toBeRemoved == null)
                        {
                            toBeRemoved = new List <KeyValuePair <Assembly, AccessorClassLoader> >();
                        }
                        toBeRemoved.Add(entry);
                        continue;
                    }
                    if (Object.ReferenceEquals(assembly, parent))
                    {
                        return(entry.Value);
                    }
                }
                if (toBeRemoved != null)
                {
                    foreach (KeyValuePair <Assembly, AccessorClassLoader> entry in toBeRemoved)
                    {
                        accessClassLoaders.Remove(entry);
                    }
                }
                AccessorClassLoader accessClassLoader = new AccessorClassLoader(parent);
                accessClassLoaders.Add(parent, accessClassLoader);
                return(accessClassLoader);
            }
        }
Exemple #4
0
        protected Type CreateConstructorType(AccessorClassLoader loader, String constructorClassName, Type delegateType, Type targetType)
        {
            if (Log.DebugEnabled)
            {
                Log.Debug("Creating fast constructor handle for " + targetType.FullName);
            }
            Type delegateTypeHandle = delegateType;
            Type objType            = typeof(Object);
            Type superType;

            TypeBuilder cw;

            if (delegateType.IsInterface)
            {
                superType = objType;
                cw        = loader.CreateNewType(TypeAttributes.Public, constructorClassName, superType, new Type[] { delegateTypeHandle });
            }
            else
            {
                superType = delegateTypeHandle;
                cw        = loader.CreateNewType(TypeAttributes.Public, constructorClassName, superType, Type.EmptyTypes);
            }
            {
                ConstructorInfo baseConstructor = superType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, Type.EmptyTypes, null);
                if (baseConstructor == null)
                {
                    throw new Exception("Constructor not found: " + superType.FullName);
                }
                ILGenerator mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, Type.EmptyTypes).GetILGenerator();
                mv.Emit(OpCodes.Ldarg_0);
                mv.Emit(OpCodes.Call, baseConstructor);
                mv.Emit(OpCodes.Ret);
            }
            MethodInfo[]      r_methods    = ReflectUtil.GetMethods(delegateType);
            ConstructorInfo[] constructors = targetType.GetConstructors();
            foreach (ConstructorInfo constructor in constructors)
            {
                ParameterInfo[] constructorParams = constructor.GetParameters();
                for (int a = r_methods.Length; a-- > 0;)
                {
                    MethodInfo r_method = r_methods[a];
                    if (r_method == null)
                    {
                        // already handled
                        continue;
                    }
                    if (!delegateType.IsInterface && !r_method.IsAbstract)
                    {
                        // only handle abstract methods
                        r_methods[a] = null;
                        continue;
                    }
                    ParameterInfo[] methodParams = r_method.GetParameters();
                    if (constructorParams.Length != methodParams.Length)
                    {
                        // no match
                        continue;
                    }
                    bool paramsEqual = true;
                    for (int b = constructorParams.Length; b-- > 0;)
                    {
                        if (!constructorParams[b].ParameterType.Equals(methodParams[b].ParameterType))
                        {
                            paramsEqual = false;
                            break;
                        }
                    }
                    if (!paramsEqual)
                    {
                        // no match
                        continue;
                    }
                    r_methods[a] = null;
                    ImplementConstructorOfConstructorType(r_method, constructor, cw);
                }
            }
            foreach (MethodInfo r_method in r_methods)
            {
                if (r_method != null)
                {
                    throw new ArgumentException("No matching constructor found on " + targetType.FullName + " to map on delegate method "
                                                + r_method.ToString());
                }
            }
            return(loader.GetType(constructorClassName, cw));
        }
Exemple #5
0
        protected Type CreateType(AccessorClassLoader loader, String accessClassName, Type targetType, IPropertyInfo property)
        {
            if (Log.DebugEnabled)
            {
                Log.Debug("Creating accessor for " + targetType.FullName + "." + property.Name);
            }
            Type abstractAccessorType = typeof(AbstractAccessor);
            Type objType = typeof(Object);

            TypeBuilder cw = loader.CreateNewType(TypeAttributes.Public, accessClassName, abstractAccessorType, Type.EmptyTypes);
            {
                ConstructorInfo baseConstructor = abstractAccessorType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Type), typeof(String) }, null);
                ILGenerator     mv = cw.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] { typeof(Type), typeof(String) }).GetILGenerator();
                mv.Emit(OpCodes.Ldarg_0);
                mv.Emit(OpCodes.Ldarg_1);
                mv.Emit(OpCodes.Ldarg_2);
                mv.Emit(OpCodes.Call, baseConstructor);
                mv.Emit(OpCodes.Ret);
            }
            MethodInfo r_get = ReflectUtil.GetDeclaredMethod(true, targetType, property.PropertyType, "get_" + property.Name, new Type[0]);

            if (r_get == null)
            {
                r_get = ReflectUtil.GetDeclaredMethod(true, targetType, property.PropertyType, "Get" + property.Name, new Type[0]);
            }
            if (r_get == null)
            {
                r_get = ReflectUtil.GetDeclaredMethod(true, targetType, property.PropertyType, "Is" + property.Name, new Type[0]);
            }
            MethodInfo r_set = ReflectUtil.GetDeclaredMethod(true, targetType, property.PropertyType, "set_" + property.Name, new Type[] { null });

            if (r_set == null)
            {
                r_set = ReflectUtil.GetDeclaredMethod(true, targetType, property.PropertyType, "Set" + property.Name, new Type[] { null });
            }
            {
                ILGenerator mv = cw.DefineMethod("get_CanRead", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(bool), Type.EmptyTypes).GetILGenerator();
                mv.Emit(r_get != null && r_get.IsPublic ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
                mv.Emit(OpCodes.Ret);
            }
            {
                ILGenerator mv = cw.DefineMethod("get_CanWrite", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(bool), Type.EmptyTypes).GetILGenerator();
                mv.Emit(r_set != null && r_set.IsPublic ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
                mv.Emit(OpCodes.Ret);
            }
            {
                ILGenerator mv = cw.DefineMethod("GetValue", MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig, CallingConventions.HasThis, typeof(Object), new Type[] { typeof(Object) }).GetILGenerator();

                if (r_get == null)
                {
                    mv.Emit(OpCodes.Ldstr, "Property not readable: " + targetType.FullName + "." + property.Name);
                    mv.ThrowException(typeof(NotSupportedException));
                }
                else
                {
                    Type owner = r_get.DeclaringType;
                    mv.Emit(OpCodes.Ldarg_1);
                    mv.Emit(OpCodes.Castclass, owner);
                    mv.Emit(OpCodes.Callvirt, r_get);
                    if (r_get.ReturnType.IsValueType)
                    {
                        mv.Emit(OpCodes.Box, r_get.ReturnType);
                    }
                }
                mv.Emit(OpCodes.Ret);
            }
            {
                MethodAttributes access = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig;
                access |= MethodAttributes.ReuseSlot;
                access &= ~MethodAttributes.VtableLayoutMask;

                ILGenerator mv = cw.DefineMethod("SetValue", access, CallingConventions.HasThis, typeof(void), new Type[] { typeof(Object), typeof(Object) }).GetILGenerator();

                if (r_set == null)
                {
                    mv.Emit(OpCodes.Ldstr, "Property not writable: " + targetType.FullName + "." + property.Name);
                    mv.ThrowException(typeof(NotSupportedException));
                }
                else
                {
                    Type owner = r_get.DeclaringType;
                    mv.Emit(OpCodes.Ldarg_1);
                    mv.Emit(OpCodes.Castclass, owner);
                    mv.Emit(OpCodes.Ldarg_2);
                    Type paramType = r_set.GetParameters()[0].ParameterType;
                    if (!objType.Equals(paramType))
                    {
                        if (paramType.IsValueType)
                        {
                            mv.Emit(OpCodes.Unbox_Any, paramType);
                        }
                        else
                        {
                            mv.Emit(OpCodes.Castclass, paramType);
                        }
                    }
                    mv.Emit(OpCodes.Callvirt, r_set);
                }
                mv.Emit(OpCodes.Ret);
            }
            return(loader.GetType(accessClassName, cw));
        }