Ejemplo n.º 1
0
        public void EmitCall(OpCode op, MethodInfo method, IEnumerable <Type> parameterTypes, Type[] arglist)
        {
            InstructionSizes.Add(() => InstructionSize.Get(op));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.EmitCall(op, method, arglist);
                }

                var mtdString = method is MethodBuilder ? method.Name : method.ToString();

                log.AppendLine(op + " " + mtdString + " __arglist(" + Join(", ", arglist) + ")");
            }
                );

            var parameters = new LinqList <Type>(parameterTypes);

            if (!method.IsStatic)
            {
                var declaring = method.DeclaringType;

                if (TypeHelpers.IsValueType(declaring))
                {
                    declaring = declaring.MakePointerType();
                }

                parameters.Insert(0, declaring);
            }

            parameters.AddRange(arglist);

            var paras = new List <object> {
                method
            };

            paras.AddRange(arglist);

            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op, MethodReturnType = method.ReturnType, MethodParameterTypes = parameters
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = paras.ToArray()
            });
        }
Ejemplo n.º 2
0
        private static Type Alias(Type t)
        {
            if (TypeHelpers.IsValueType(t) && TypeHelpers.IsEnum(t))
            {
                return(Alias(Enum.GetUnderlyingType(t)));
            }

            Type ret;

            if (!_AliasCache.TryGetValue(t, out ret))
            {
                ret = t;
            }

            return(ret);
        }
Ejemplo n.º 3
0
        private static LinqList <Type> GetBases(Type t)
        {
            if (TypeHelpers.IsValueType(t))
            {
                return(new LinqList <Type>());
            }

            var ret = new LinqList <Type>();

            t = TypeHelpers.GetBaseType(t);

            while (t != null)
            {
                ret.Add(t);
                t = TypeHelpers.GetBaseType(t);
            }

            return(ret);
        }
Ejemplo n.º 4
0
        public void Emit(OpCode op, ConstructorInfo cons, IEnumerable <Type> parameterTypes)
        {
            InstructionSizes.Add(() => InstructionSize.Get(op));

            LengthCache.Clear();

            Buffer.Add(
                (il, logOnly, log) =>
            {
                if (!logOnly)
                {
                    il.Emit(op, cons);
                }

                var mtdString = cons is ConstructorBuilder ? cons.Name : cons.ToString();

                log.AppendLine(op + " " + mtdString);
            }
                );

            var parameters = new LinqList <Type>(parameterTypes);
            var declaring  = cons.DeclaringType;

            if (TypeHelpers.IsValueType(declaring))
            {
                declaring = declaring.MakePointerType();
            }

            parameters.Insert(0, declaring);


            TraversableBuffer.Add(new BufferedILInstruction {
                IsInstruction = op, MethodReturnType = typeof(void), MethodParameterTypes = parameters
            });

            Operations.Add(new Operation <DelegateType> {
                OpCode = op, Parameters = new object[] { cons }
            });
        }
Ejemplo n.º 5
0
        public static bool IsAssignableFrom(TypeOnStack type1, TypeOnStack type2)
        {
            // voids aren't assignable
            if (type1.IsVoid || type2.IsVoid)
            {
                return(false);
            }

            // wildcards match *everything*
            if (type1 == TypeOnStack.Get <WildcardType>() || type2 == TypeOnStack.Get <WildcardType>())
            {
                return(true);
            }

            if (type1.IsArray && type2.IsArray)
            {
                if (type1.Type.GetArrayRank() == type2.Type.GetArrayRank())
                {
                    var t1Elem = type1.Type.GetElementType();
                    var t2Elem = type2.Type.GetElementType();

                    while (t1Elem.HasElementType)
                    {
                        t1Elem = t1Elem.GetElementType();
                    }
                    while (t2Elem.HasElementType)
                    {
                        t2Elem = t2Elem.GetElementType();
                    }

                    if (t1Elem == typeof(WildcardType) || t2Elem == typeof(WildcardType))
                    {
                        return(true);
                    }
                }
            }

            if (type1.IsPointer && type2.IsPointer)
            {
                if (type1.Type.GetElementType() == typeof(WildcardType) || type2.Type.GetElementType() == typeof(WildcardType))
                {
                    return(true);
                }
            }

            if (type1.IsReference && type2.IsReference)
            {
                if (type1.Type.GetElementType() == typeof(WildcardType) || type2.Type.GetElementType() == typeof(WildcardType))
                {
                    return(true);
                }
            }

            // any pointer type matches, well, any pointer
            if (type1.Type == typeof(AnyPointerType) && type2.IsPointer)
            {
                return(true);
            }
            if (type2.Type == typeof(AnyPointerType) && type1.IsPointer)
            {
                return(true);
            }

            // likewise for any by ref
            if (type1.Type == typeof(AnyByRefType) && type2.IsReference)
            {
                return(true);
            }
            if (type2.Type == typeof(AnyByRefType) && type1.IsReference)
            {
                return(true);
            }

            // Native int can be convereted to any pointer type
            if (type1.IsPointer && type2 == TypeOnStack.Get <NativeIntType>())
            {
                return(true);
            }
            if (type2.IsPointer && type1 == TypeOnStack.Get <NativeIntType>())
            {
                return(true);
            }

            // it's possible to assign a struct* to an interface or object
            if (!(type2.IsPointerToValueType && (type1.IsInterface || type1.Type.Equals(typeof(object)))))
            {
                if ((type1.IsPointer || type1.IsReference) && !(type2.IsPointer || type2.IsReference))
                {
                    return(false);
                }
                if ((type2.IsPointer || type2.IsReference) && !(type1.IsPointer || type1.IsReference))
                {
                    return(false);
                }
            }

            if (type1.IsPointer || type1.IsReference)
            {
                return(type1.Type.GetElementType() == type2.Type.GetElementType());
            }

            var t1 = type1.Type;
            var t2 = type2.Type;


            // The null type can be assigned to any reference type
            if (t1 == typeof(NullType) && !TypeHelpers.IsValueType(t2))
            {
                return(true);
            }
            if (t2 == typeof(NullType) && !TypeHelpers.IsValueType(t1))
            {
                return(true);
            }

            t1 = Alias(t1);
            t2 = Alias(t2);

            return(ReallyIsAssignableFrom(t1, t2));
        }
Ejemplo n.º 6
0
        private static bool ReallyIsAssignableFrom(Type t1, Type t2)
        {
            if (t1 == t2)
            {
                return(true);
            }

            if (t1 == typeof(OnlyObjectType))
            {
                if (t2 == typeof(object))
                {
                    return(true);
                }

                return(false);
            }

            // quick and dirty base case
            if (t1 == typeof(object) && !TypeHelpers.IsValueType(t2))
            {
                return(true);
            }

            // you have to box in this case
            if ((t1 == typeof(object) || TypeHelpers.IsInterface(t1)) && TypeHelpers.IsValueType(t2))
            {
                return(false);
            }

            var t1Bases = GetBases(t1);
            var t2Bases = GetBases(t2);

            if (t2Bases.Any(t2b => TypeOnStack.Get(t1).IsAssignableFrom(TypeOnStack.Get(t2b))))
            {
                return(true);
            }

            if (TypeHelpers.IsInterface(t1))
            {
                var t2Interfaces = t2.IsPointer ? (LinqArray <Type>)t2.GetElementType().GetInterfaces() : (LinqArray <Type>)t2.GetInterfaces();

                return(t2Interfaces.Any(t2i => TypeOnStack.Get(t1).IsAssignableFrom(TypeOnStack.Get(t2i))));
            }

            if (TypeHelpers.IsGenericType(t1) && TypeHelpers.IsGenericType(t2))
            {
                var t1Def = t1.GetGenericTypeDefinition();
                var t2Def = t2.GetGenericTypeDefinition();

                if (t1Def != t2Def)
                {
                    return(false);
                }

                var t1Args = t1.GetGenericArguments();
                var t2Args = t2.GetGenericArguments();

                for (var i = 0; i < t1Args.Length; i++)
                {
                    if (!TypeOnStack.Get(t1Args[i]).IsAssignableFrom(TypeOnStack.Get(t2Args[i])))
                    {
                        return(false);
                    }
                }

                return(true);
            }

            try
            {
                return(t1.IsAssignableFrom(t2));
            }
            catch (NotSupportedException)
            {
                // Builders, some generic types, and so on don't implement this; just assume it's *no good* for now
                return(false);
            }
        }