Exemplo n.º 1
0
 protected static void CheckCanBeAssigned(GroboIL il, Type to, ESType from)
 {
     if (!CanBeAssigned(to, from, il.VerificationKind))
     {
         ThrowError(il, $"Unable to set a value of type '{@from}' to an instance of type '{Formatter.Format(to)}'");
     }
 }
Exemplo n.º 2
0
        private static bool EqualESTypes(ESType first, ESType second)
        {
            if ((first is SimpleESType) ^ (second is SimpleESType))
            {
                return(false);
            }
            if (first.ToType() != second.ToType())
            {
                return(false);
            }
            if (first is SimpleESType)
            {
                return(true);
            }
            var firstInterfaces  = new HashSet <Type>(((ComplexESType)first).Interfaces);
            var secondInterfaces = ((ComplexESType)second).Interfaces;

            foreach (var type in secondInterfaces)
            {
                if (!firstInterfaces.Contains(type))
                {
                    return(false);
                }
                firstInterfaces.Remove(type);
            }
            return(firstInterfaces.Count == 0);
        }
Exemplo n.º 3
0
 protected static void CheckNotStruct(GroboIL il, ESType type)
 {
     if (ToCLIType(type) == CLIType.Struct)
     {
         ThrowError(il, $"Struct of type '{type}' is not valid at this point");
     }
 }
Exemplo n.º 4
0
 protected static void CheckNotStruct(GroboIL il, ESType type)
 {
     if (ToCLIType(type) == CLIType.Struct)
     {
         ThrowError(il, string.Format("Struct of type '{0}' is not valid at this point", type));
     }
 }
Exemplo n.º 5
0
        private static bool CanBeAssigned(Type to, ESType esFrom)
        {
            var cliTo   = ToCLIType(to);
            var cliFrom = ToCLIType(esFrom);
            var from    = esFrom.ToType();

            switch (cliTo)
            {
            case CLIType.Int32:
                return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero);

            case CLIType.NativeInt:
                return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero);

            case CLIType.Int64:
                return(cliFrom == CLIType.Int64 || cliFrom == CLIType.Zero);

            case CLIType.Float:
                return(cliFrom == CLIType.Float || cliFrom == CLIType.Zero);

            case CLIType.Struct:
                return(ReflectionExtensions.Equal(to, from));

            case CLIType.Pointer:
                if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from))
                {
                    return(true);
                }
                if (cliFrom != CLIType.Pointer)
                {
                    return(false);
                }
                to   = to.GetElementType();
                from = from.GetElementType();
                return(to.IsValueType && from.IsValueType);

            case CLIType.Object:
                if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from))
                {
                    return(true);
                }
                if (cliFrom != CLIType.Object)
                {
                    return(false);
                }
                var simpleESFrom = esFrom as SimpleESType;
                if (simpleESFrom != null)
                {
                    return(ReflectionExtensions.IsAssignableFrom(to, from));
                }
                var complexESFrom = (ComplexESType)esFrom;
                return(ReflectionExtensions.IsAssignableFrom(to, complexESFrom.BaseType) || complexESFrom.Interfaces.Any(interfaCe => ReflectionExtensions.IsAssignableFrom(to, interfaCe)));

            case CLIType.Zero:
                return(true);

            default:
                throw new InvalidOperationException(string.Format("CLI type '{0}' is not valid at this point", cliTo));
            }
        }
Exemplo n.º 6
0
 protected static void CheckCanBeAssigned(GroboIL il, Type to, ESType from)
 {
     if (!CanBeAssigned(to, from))
     {
         ThrowError(il, string.Format("Unable to set a value of type '{0}' to an instance of type '{1}'", from, Formatter.Format(to)));
     }
 }
Exemplo n.º 7
0
        protected static void CheckIsAPointer(GroboIL il, ESType type)
        {
            var cliType = ToCLIType(type);

            if (cliType != CLIType.Pointer && cliType != CLIType.NativeInt)
            {
                ThrowError(il, $"A pointer type expected but was '{type}'");
            }
        }
Exemplo n.º 8
0
        private static CLIType ToLowLevelCLIType(ESType esType)
        {
            if (esType == null)
            {
                return(CLIType.NativeInt);
            }
            var simpleESType = esType as SimpleESType;

            return(simpleESType == null ? CLIType.NativeInt : ToLowLevelCLIType(simpleESType.Type)); // ComplexESType is always an object
        }
Exemplo n.º 9
0
        protected static CLIType ToCLIType(ESType esType)
        {
            if (esType == null)
            {
                return(CLIType.Zero);
            }
            var simpleESType = esType as SimpleESType;

            return(simpleESType == null ? CLIType.Object : ToCLIType(simpleESType.Type)); // ComplexESType is always an object
        }
Exemplo n.º 10
0
 private static StacksComparisonResult CompareStacks(ESType[] first, ESType[] second, out ESType[] merged)
 {
     merged = null;
     if (first.Length != second.Length)
     {
         return(StacksComparisonResult.Inconsistent);
     }
     ESType[] result = null;
     for (var i = 0; i < first.Length; ++i)
     {
         var firstCLIType  = ToCLIType(first[i]);
         var secondCLIType = ToCLIType(second[i]);
         if (firstCLIType != CLIType.Zero && secondCLIType != CLIType.Zero && firstCLIType != secondCLIType)
         {
             return(StacksComparisonResult.Inconsistent);
         }
         if (!EqualESTypes(first[i], second[i]))
         {
             var common = FindCommonType(firstCLIType, first[i], second[i]);
             if (common == null)
             {
                 return(StacksComparisonResult.Inconsistent);
             }
             if (result == null)
             {
                 result = new ESType[first.Length];
                 for (var j = 0; j < i; ++j)
                 {
                     result[j] = first[j];
                 }
             }
             result[i] = common;
         }
         else if (result != null)
         {
             result[i] = first[i];
         }
     }
     if (result == null)
     {
         return(StacksComparisonResult.Equal);
     }
     merged = result;
     return(StacksComparisonResult.Equivalent);
 }
Exemplo n.º 11
0
        private static ESType FindCommonType(CLIType cliType, ESType first, ESType second)
        {
            if (first.ToType() == null)
            {
                return(second);
            }
            if (second.ToType() == null)
            {
                return(first);
            }
            switch (cliType)
            {
            case CLIType.Int32:
                return(new SimpleESType(typeof(int)));

            case CLIType.Int64:
                return(new SimpleESType(typeof(long)));

            case CLIType.Float:
                return(new SimpleESType(typeof(double)));

            case CLIType.NativeInt:
            {
                if (((SimpleESType)first).Type.IsPointer && ((SimpleESType)second).Type.IsPointer)
                {
                    return(new SimpleESType(typeof(void).MakePointerType()));
                }
                return(new SimpleESType(typeof(IntPtr)));
            }

            case CLIType.Pointer:
            {
                var firstElementType  = ((SimpleESType)first).Type.GetElementType();
                var secondElementType = ((SimpleESType)second).Type.GetElementType();
                if (!firstElementType.IsValueType || !secondElementType.IsValueType)
                {
                    return(null);
                }
                return(Marshal.SizeOf(firstElementType) <= Marshal.SizeOf(secondElementType) ? first : second);
            }

            case CLIType.Struct:
                return(null);

            case CLIType.Object:
            {
                var baseType        = first.ToType().FindBaseClassWith(second.ToType());
                var firstInterfaces = new HashSet <Type>(new ReflectionExtensions.TypesComparer());
                if (first is SimpleESType)
                {
                    ((SimpleESType)first).Type.GetInterfacesCollectionStupid(firstInterfaces);
                }
                else
                {
                    ((ComplexESType)first).BaseType.GetInterfacesCollectionStupid(firstInterfaces);
                    foreach (var interfaCe in ((ComplexESType)first).Interfaces)
                    {
                        firstInterfaces.Add(interfaCe);
                    }
                }
                var secondInterfaces = new HashSet <Type>(new ReflectionExtensions.TypesComparer());
                if (second is SimpleESType)
                {
                    ((SimpleESType)second).Type.GetInterfacesCollectionStupid(secondInterfaces);
                }
                else
                {
                    ((ComplexESType)second).BaseType.GetInterfacesCollectionStupid(secondInterfaces);
                    foreach (var interfaCe in ((ComplexESType)second).Interfaces)
                    {
                        secondInterfaces.Add(interfaCe);
                    }
                }
                HashSet <Type> intersected;
                if (firstInterfaces.Count > secondInterfaces.Count)
                {
                    firstInterfaces.IntersectWith(secondInterfaces);
                    intersected = firstInterfaces;
                }
                else
                {
                    secondInterfaces.IntersectWith(firstInterfaces);
                    intersected = secondInterfaces;
                }
                intersected.Add(baseType);

                //var firstInterfaces = ((first is SimpleESType)
                //                           ? ((SimpleESType)first).Type.GetTypesArray()
                //                           : ((ComplexESType)first).BaseType.GetTypesArray().Concat(((ComplexESType)first).Interfaces)).Where(t => t.IsInterface).ToArray();
                //var secondInterfaces = ((second is SimpleESType)
                //                            ? ((SimpleESType)second).Type.GetTypesArray()
                //                            : ((ComplexESType)second).BaseType.GetTypesArray().Concat(((ComplexESType)second).Interfaces)).Where(t => t.IsInterface).ToArray();
                //var hashSet = new HashSet<Type>(firstInterfaces.Intersect(secondInterfaces).Concat(new[] {baseType}), new ReflectionExtensions.TypesComparer());
                while (true)
                {
                    var end = true;
                    foreach (var type in intersected.ToArray())
                    {
                        var children = ReflectionExtensions.GetInterfaces(type);
                        foreach (var child in children)
                        {
                            if (intersected.Contains(child))
                            {
                                end = false;
                                intersected.Remove(child);
                            }
                        }
                    }
                    if (end)
                    {
                        break;
                    }
                }
                intersected.Remove(baseType);
                if (intersected.Count == 0)
                {
                    return(new SimpleESType(baseType));
                }
                return(new ComplexESType(baseType, intersected.ToArray()));
            }

            default:
                throw new InvalidOperationException($"CLI type '{cliType}' is not valid at this point");
            }
        }
Exemplo n.º 12
0
        private static bool CanBeAssigned(Type to, ESType esFrom, TypesAssignabilityVerificationKind verificationKind)
        {
            if (verificationKind == TypesAssignabilityVerificationKind.None)
            {
                return(true);
            }
            var cliTo   = verificationKind == TypesAssignabilityVerificationKind.HighLevel ? ToCLIType(to) : ToLowLevelCLIType(to);
            var cliFrom = verificationKind == TypesAssignabilityVerificationKind.HighLevel ? ToCLIType(esFrom) : ToLowLevelCLIType(esFrom);

            var from = esFrom.ToType();

            switch (cliTo)
            {
            case CLIType.Int32:
                return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero);

            case CLIType.NativeInt:
                return(cliFrom == CLIType.Int32 || cliFrom == CLIType.NativeInt || cliFrom == CLIType.Zero);

            case CLIType.Int64:
                return(cliFrom == CLIType.Int64 || cliFrom == CLIType.Zero);

            case CLIType.Float:
                return(cliFrom == CLIType.Float || cliFrom == CLIType.Zero);

            case CLIType.Struct:
                return(ReflectionExtensions.Equal(to, from));

            case CLIType.Pointer:
                if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from))
                {
                    return(true);
                }
                if (cliFrom != CLIType.Pointer)
                {
                    return(false);
                }
                to   = to.GetElementType();
                from = from.GetElementType();
                return(to.IsValueType && from.IsValueType);

            case CLIType.Object:
                if (cliFrom == CLIType.Zero || ReflectionExtensions.Equal(to, from))
                {
                    return(true);
                }
                if (cliFrom != CLIType.Object)
                {
                    return(false);
                }
                var simpleESFrom = esFrom as SimpleESType;
                if (simpleESFrom != null)
                {
                    return(ReflectionExtensions.IsAssignableFrom(to, from));
                }
                var complexESFrom = (ComplexESType)esFrom;
                return(ReflectionExtensions.IsAssignableFrom(to, complexESFrom.BaseType) || complexESFrom.Interfaces.Any(interfaCe => ReflectionExtensions.IsAssignableFrom(to, interfaCe)));

            case CLIType.Zero:
                return(true);

            default:
                throw new InvalidOperationException($"CLI type '{cliTo}' is not valid at this point");
            }
        }
Exemplo n.º 13
0
 protected static Type Canonize(ESType esType)
 {
     return(Canonize(esType.ToType()));
 }