/// <summary> /// Includes what are the types supported /// </summary> /// <returns></returns> public static bool IsTypeSupported(TypeEx type) { if (type.Spec == TypeSpec.SzArray || type.IsPrimitiveImmutable || PrimitiveTypes.Contains(type) || type.IsStringType || type.Spec == TypeSpec.Class) { return(true); } return(false); }
public void SubstituteWorks() { var type = TypeEx.Substitute(typeof(Tuple <string, int, List <string>, double>), t => t == typeof(string) ? typeof(decimal) : t); Assert.Equal(typeof(Tuple <decimal, int, List <decimal>, double>), type); var type2 = TypeEx.Substitute(typeof(int), t => typeof(string)); Assert.Equal(typeof(string), type2); }
static LazyDictionary() { try { DefaultValueFactory = TypeEx <TValue> .CreateConstructorDelegate(); } catch (Exception ex) { DefaultValueFactoryCreateException = ex; } }
public ObjectSerializer(Type type) { if (null == type) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.type); } Type = type; //TODO: remove version info //var typeName = type.GetShortAssemblyQualifiedName(); // ReSharper disable once PossibleNullReferenceException // ReSharper disable once AssignNullToNotNullAttribute var typeKey = AntTypeSerializer.GetTypeKeyFromType(type); var typeNameBytes = typeKey.TypeName; var hashCodeBytes = BitConverter.GetBytes(typeKey.HashCode); var fields = type.GetFieldInfosForType(); var fieldNames = fields.Select(field => field.Name.ToUtf8Bytes()).ToList(); var versionInfo = TypeEx.GetTypeManifest(fieldNames); //precalculate the entire manifest for this serializer //this helps us to minimize calls to Stream.Write/WriteByte _manifest = new[] { ManifestFull } .Concat(BitConverter.GetBytes(typeNameBytes.Length)) .Concat(typeNameBytes) .Concat(hashCodeBytes) .ToArray(); //serializer id 255 + assembly qualified name //TODO: this should only work this way for standard poco objects //custom object serializers should not emit their inner fields //this is the same as the above, but including all field names of the type, in alphabetical order _manifestWithVersionInfo = new[] { ManifestVersion } .Concat(BitConverter.GetBytes(typeNameBytes.Length)) .Concat(typeNameBytes) .Concat(hashCodeBytes) .Concat(versionInfo) .ToArray(); //serializer id 255 + assembly qualified name + versionInfo //initialize reader and writer with dummy handlers that wait until the serializer is fully initialized _writer = (stream, o, session) => { SpinWait.SpinUntil(() => _isInitialized); WriteValue(stream, o, session); }; _reader = (stream, session) => { SpinWait.SpinUntil(() => _isInitialized); return(ReadValue(stream, session)); }; }
/// <summary> /// Adds a type to predefined classes store /// </summary> /// <param name="typename"></param> /// <param name="typeEx"></param> public void AddToPredinedStore(string typename, TypeEx typeEx) { SafeList <TypeEx> existingDefinedTypes; if (!definedTypes.TryGetValue(typename, out existingDefinedTypes)) { existingDefinedTypes = new SafeList <TypeEx>(); definedTypes.Add(typename, existingDefinedTypes); } existingDefinedTypes.Add(typeEx); }
private static bool IsPlaying() { if (!Application.isEditor) { return(true); } System.Type type = TypeEx.GetType("UnityEditor.EditorApplication"); PropertyInfo p = type.GetProperty("isPlayingOrWillChangePlaymode", BindingFlags.Static | BindingFlags.Public); MethodInfo method = p.GetGetMethod(); bool isChange = (bool)method.Invoke(null, null); return(Application.isPlaying && isChange); }
/// <summary> /// Returns a method that produce a given type. Static methods are given higher preference than dynamic methods /// </summary> /// <param name="targetTypeEx"></param> /// <param name="producingMethods"></param> /// <returns></returns> public static bool TryGetProducingMethods(PexMeDynamicDatabase pmd, TypeEx targetTypeEx, out Method producingMethod) { var currAssembly = pmd.CurrAssembly; foreach (var tdef in currAssembly.TypeDefinitions) { if (IsAPexClass(tdef)) { continue; } foreach (var smdef in tdef.DeclaredStaticMethods) { if (IsAPexMethod(smdef)) { continue; } if (!smdef.IsVisible(VisibilityContext.Exported)) { continue; } if (TryCheckReturnTypeOfMethod(pmd, tdef, smdef, targetTypeEx, out producingMethod)) { return(true); } } foreach (var mdef in tdef.DeclaredInstanceMethods) { if (IsAPexMethod(mdef)) { continue; } if (!mdef.IsVisible(VisibilityContext.Exported)) { continue; } if (TryCheckReturnTypeOfMethod(pmd, tdef, mdef, targetTypeEx, out producingMethod)) { return(true); } } } producingMethod = null; return(false); }
/// <summary> /// Returns the loaded factory methods /// </summary> /// <param name="typeEx"></param> /// <returns></returns> public IEnumerable <PexExplorableCandidate> GetMSeqGenFactories(TypeEx typeEx) { SafeList <PexExplorableCandidate> existingList; if (!this.recommendedFactories.TryGetValue(typeEx.FullName, out existingList)) { yield break; } foreach (var factory in existingList) { yield return(factory); } }
CallFrame current; //aliases last ("top") element of callStack. public static SafeDictionary <TypeEx, bool> GetUninstrumentedTypes() { var result = new SafeDictionary <TypeEx, bool>(); foreach (var m in instrumentedUninstrumentedMethods.Keys) { TypeEx type = null; if (instrumentedUninstrumentedMethods2[m].TryGetDeclaringType(out type)) { result.Add(type, instrumentedUninstrumentedMethods[m]); } } return(result); }
protected internal override void VisitLoadFieldAddr(LoadFieldAddr node, object data) { StackTypes stack = data as StackTypes; if (node.Field.IsStatic) { stack.Push(TypeEx.BuildRefType(node.Field.FieldType)); } else { Verifier.ProcessLdFld(stack, node.Field, true); } AddTask(node.Next, stack); }
public MethodInfo GetSubstituted(string name, int genericArgCount, Type[] arguments) { if (genericArgCount == 0) { return(Get(name, arguments)); } MethodInfo[] methods; if (!_methods.TryGetValue(name, out methods)) { return(null); } foreach (var methodInfo in methods) { if (!methodInfo.IsGenericMethodDefinition) { continue; } var args = methodInfo.GetGenericArguments(); if (args.Length != genericArgCount) { continue; } var methodParameters = methodInfo.GetParameters(); if (methodParameters.Length != arguments.Length) { continue; } var subFunc = Substitute.GetSubstitutionFunction(args); var matched = true; for (var i = 0; i < methodParameters.Length; i++) { if (methodParameters[i].ParameterType == TypeEx.Substitute(arguments[i], subFunc)) { continue; } matched = false; break; } if (matched) { return(methodInfo); } } return(null); }
public void FindIEnumerableWorks() { Assert.Equal( new[] { typeof(string), typeof(int), typeof(double), typeof(object) }, TypeEx.FindIEnumerable(typeof(ITestEnumerable))); Assert.Equal(new[] { typeof(char), typeof(object) }, TypeEx.FindIEnumerable(typeof(string))); Assert.Equal(new[] { typeof(int), typeof(object) }, TypeEx.FindIEnumerable(typeof(List <int>))); Assert.Equal(new[] { typeof(object) }, TypeEx.FindIEnumerable(typeof(SomeEnumerable))); Assert.Equal( new[] { typeof(char), typeof(object) }, TypeEx.FindIEnumerable(typeof(IEnumerable <char>))); Assert.Equal(new[] { typeof(object) }, TypeEx.FindIEnumerable(typeof(IEnumerable))); Assert.Equal(2, TypeEx.FindIEnumerable(typeof(IEnumerable <>)).Count()); Assert.False(TypeEx.FindIEnumerable(typeof(int)).Any()); }
public void InitEnumTypeSelector(Type baseType, string enumTypeVar) { this.enumTypeFieldName = enumTypeVar; if (enumTypeSelector == null) { enumTypeSelector = new TypeSelector(baseType); } else { enumTypeSelector.SetBaseType(baseType); } string enumTypeName = obj.GetFieldValue <string>(enumTypeVar); enumTypeSelector.SetSelected(TypeEx.GetType(enumTypeName)); }
//this returns a delegate for serializing a specific "field" of an instance of type "type" public void Serialize(object obj, [NotNull] Stream stream, SerializerSession session) { if (obj == null) { throw new ArgumentNullException(nameof(obj)); } if (session == null) { throw new ArgumentNullException(nameof(session)); } var type = obj.GetType(); if (Options.DisallowUnsafeTypes) { if (AcceptedTypes.TryGetValue(type, out var acceptance)) { if (!acceptance.Accepted) { if (acceptance.UserRejected) { throw new UserEvilDeserializationException("Unsafe Type Deserialization Detected!", type.FullName); } throw new EvilDeserializationException("Unsafe Type Deserialization Detected!", type.FullName); } } else { if (TypeEx.IsDisallowedType(type)) { AcceptedTypes[type] = new TypeAccepted(false, false); throw new EvilDeserializationException("Unsafe Type Deserialization Detected!", type.FullName); } if (!Options.TypeFilter.IsAllowed(type.AssemblyQualifiedName)) { AcceptedTypes[type] = new TypeAccepted(false, true); throw new UserEvilDeserializationException("Unsafe Type Deserialization Detected!", type.FullName); } AcceptedTypes[type] = new TypeAccepted(true, false); } } var s = GetSerializerByType(type); s.WriteManifest(stream, session); s.WriteValue(stream, obj, session); }
/// <summary> /// Retrieves some typeEx for the generic typename /// </summary> /// <returns></returns> public bool TryGetSomeTypeEx(out TypeEx typeEx) { typeEx = null; foreach (var definedType in this.definedTypes.Values) { if (definedType.Count == 0) { continue; } typeEx = definedType[0]; return(true); } return(true); }
/// <summary> /// Gets the type definition of a field /// </summary> /// <param name="host"></param> /// <param name="field"></param> /// <param name="ftex"></param> /// <returns></returns> public static bool TryGetDeclaringTypeEx(IPexComponent host, Field field, out TypeEx ftex) { var fdefinition = field.Definition; TypeDefinition td; if (!fdefinition.TryGetDeclaringType(out td)) { host.Log.LogError(WikiTopics.MissingWikiTopic, "fieldanalyzer", "Failed to retrieve the declaring type of the field " + field.FullName); ftex = null; return(false); } ftex = td.Instantiate(GetGenericTypeParameters(host, td)); return(true); }
public IEnumerable<Type> CollectAssetTypes() { yield return typeof(GameObject); yield return typeof(Material); yield return typeof(Texture); yield return typeof(SceneAsset); yield return typeof(ScriptableObject); var assemblies = AppDomain.CurrentDomain.GetAssemblies(); var gameAssembly = assemblies.Single(a => a.FullName.Contains("Assembly-CSharp,")); var soTypes = TypeEx.GetSubclasses<ScriptableObject>(true, gameAssembly); foreach (var type in soTypes) { yield return type; } }
public void TypeEx_ToQualifiedAssemblyName_should_strip_version_correctly_for_mscorlib_substitution() { var version = TypeEx.ToQualifiedAssemblyName( "System.Collections.Immutable.ImmutableDictionary`2[[System.String, mscorlib,%core%],[System.Int32, mscorlib,%core%]]," + " System.Collections.Immutable, Version=1.2.1.0, PublicKeyToken=b03f5f7f11d50a3a", ignoreAssemblyVersion: true); var coreAssemblyName = typeof(TypeEx).GetField("CoreAssemblyName", BindingFlags.Static | BindingFlags.NonPublic)?.GetValue(null); if (coreAssemblyName == null) { throw new Exception($"CoreAssemblyName private static field does not exist in {nameof(TypeEx)} class anymore"); } version.Should().Be("System.Collections.Immutable.ImmutableDictionary`2" + $"[[System.String, mscorlib{coreAssemblyName}],[System.Int32, mscorlib{coreAssemblyName}]], System.Collections.Immutable"); }
private void GetCallingMethods(Field field, TypeEx declaringType, SafeSet <Method> writeMethods, SafeSet <Method> newWriteMethods) { foreach (var writeM in writeMethods) { if (writeM.Definition.DeclaredVisibility != Visibility.Private || writeM.IsConstructor) { newWriteMethods.Add(writeM); continue; } //Get other calling methods within this type SafeSet <Method> localCM; if (this.TryGetCallingMethodsInType(writeM, field, declaringType, out localCM)) { newWriteMethods.AddRange(localCM); } } }
public override object ReadValue(Stream stream, DeserializerSession session) { var shortname = stream.ReadString(session); if (shortname == null) { return(null); } var type = TypeEx.LoadTypeByName(shortname); //add the deserialized type to lookup if (session.Serializer.Options.PreserveObjectReferences) { session.TrackDeserializedObject(type); } return(type); }
public bool TryGetTypeHints(TypeEx type, out IIndexable <TypeDefinition> hints) { hints = null; if (!PexMeConstants.ENABLE_TYPE_HINT_PROVIDER) { return(false); } hints = null; this.pmd.Log.LogMessage("Hint provider", "Requested for types of interface or class: " + type.FullName.ToString()); if (TypeAnalyzer.TryGetExtendingClasses(this.psd, type, out hints)) { return(true); } return(false); }
/// <summary> /// The parameters should be related through inheritance, which is a /// pre-condition and both should not be interfaces. prefers declaringType2 over declaringType1, /// incase conflict is not resolved, since declaringType2 is the actual fields declaring type /// </summary> /// <param name="declaringType1"></param> /// <param name="declaringType2"></param> /// <returns></returns> private TypeEx ChooseADeclaringType(TypeEx declaringType1, TypeEx declaringType2) { //Ensure atleast one of them is not interface if (declaringType1.IsInterface && declaringType2.IsInterface) { return(null); } //Ensure atleast one of them is not abstract if (declaringType1.IsAbstract && declaringType2.IsAbstract) { return(null); } if (declaringType1.IsInterface || declaringType1.IsAbstract) { if (!declaringType2.IsAbstract) { return(declaringType2); } } if (declaringType2.IsInterface || declaringType2.IsAbstract) { if (!declaringType1.IsAbstract) { return(declaringType1); } } //If an object is assignable to another class, then the other class //is more abstract than the current class. if (declaringType2.IsAssignableTo(declaringType1)) { return(declaringType2); } else if (declaringType1.IsAssignableTo(declaringType2)) { return(declaringType1); } return(declaringType2); }
public ValueSerializer GetDeserializerByManifest([NotNull] Stream stream, [NotNull] DeserializerSession session) { var first = stream.ReadByte(); if (first <= 250) { return(_deserializerLookup[first]); } switch (first) { case ConsistentArraySerializer.Manifest: return(ConsistentArraySerializer.Instance); case ObjectReferenceSerializer.Manifest: return(ObjectReferenceSerializer.Instance); case ObjectSerializer.ManifestFull: { var type = TypeEx.GetTypeFromManifestFull(stream, session); return(GetCustomDeserializer(type)); } case ObjectSerializer.ManifestVersion: { var type = TypeEx.GetTypeFromManifestVersion(stream, session); return(GetCustomDeserializer(type)); } case ObjectSerializer.ManifestIndex: { var typeId = (int)stream.ReadUInt16(session); if (typeId < _knownValueSerializers.Length) { return(_knownValueSerializers[typeId]); } var type = TypeEx.GetTypeFromManifestIndex(typeId, session); return(GetCustomDeserializer(type)); } default: throw new NotSupportedException("Unknown manifest value"); } }
public PersistentUncoveredLocationStore(CodeLocation cl, TypeEx explorableType, int termIndex, int fitnessvalue, FactorySuggestionStore fss) { this.CodeLocation = cl.ToString(); this.MethodSignature = MethodOrFieldAnalyzer.GetMethodSignature(cl.Method); TypeDefinition declaringType; if (!cl.Method.TryGetDeclaringType(out declaringType)) { //TODO:Error } this.ExplorableType = explorableType.ToString(); this.Offset = cl.Offset; this.AssemblyShortName = declaringType.Module.Assembly.Location; this.declaringTypeStr = declaringType.ToString(); this.Fitnessvalue = fitnessvalue; this.TermIndex = termIndex; this.parentfss = fss; }
static void Main(string[] args) { var type = typeof(IExercise); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p)).ToList <Type>(); List <IExercise> exercises = new List <IExercise>(); foreach (Type TypeEx in types) { if (TypeEx != typeof(IExercise)) { exercises.Add((IExercise)Activator.CreateInstance(Type.GetType(TypeEx.ToString()))); } } foreach (IExercise ex in exercises) { ex.Solve(); } }
/// <summary> /// 获取数据库访问工厂实例 /// </summary> /// <param name="dbFactoryName">数据库工厂类型名称</param> /// <returns>数据库访问工厂实例</returns> private static IDBFactory GetDBFactoryByDBFactoryName(string dbFactoryName) { Type type = TypeEx.GetType(dbFactoryName, true); if (type == null) { throw new ApplicationException(string.Format("获取名称为{0}数据库创建工厂实例失败", dbFactoryName)); } IDBFactory dbFactory; if (_dbFactoryDic.TryGetValue(type, out dbFactory)) { return(dbFactory); } else { throw new ApplicationException(string.Format("获取名称为{0}数据库创建工厂实例失败", dbFactoryName)); } }
public bool TryGetComponent <T>(Guid id, out T component) where T : class, IIdentifiedComponent { if (Cache <T> .Instance.Parts.TryGetValue(id, out component)) { return(true); } if (_componentIdToAssemblyQualifiedTypeName.TryGetValue(id, out var value)) { var type = TypeEx.GetType(value); component = Activator.CreateInstance(type) as T; if (component != null) { Cache <T> .Instance.AddPart(component); return(true); } } return(false); }
private void processArrayResult(PexTrackingFrame frame, Field f, TypeEx type, Term initialElementValue, Term fieldValue, Term initialValue) { //below handles array-type fields if (type.Spec == TypeSpec.SzArray && //is array !this.TermManager.IsDefaultValue(fieldValue)) //is not null pointer { Term index = this.TermManager.Symbol(SzArrayIndexId.Instance); Term elementValue = frame.Thread.State.ReadSzArrayElement(type.ElementType.Layout, fieldValue, index); if (elementValue != initialElementValue) { this.explorationObserver.HandleMonitoredField( frame.Method, f, new Term[] { index }, this.TermManager.Widen(elementValue, type.ElementType.StackWidening), initialValue); //some complicated trick, no need to know } } }
/// <summary> /// Tries to get a property that returns a given field. Needs to go base classes /// also /// </summary> /// <param name="host"></param> /// <param name="type"></param> /// <param name="field"></param> /// <param name="property"></param> /// <returns></returns> public static bool TryGetPropertyReadingField(IPexComponent host, TypeEx type, Field field, out Property property) { if (type == null) { property = null; return(false); } if (type.DeclaredProperties != null) { foreach (Property prop in type.DeclaredProperties) { Method getter = prop.Getter; if (getter == null) { continue; } MethodEffects me; if (TryComputeMethodEffects(host, type, getter, null, out me) && me.ReturnFields.Contains(field)) { property = prop; return(true); } } } var baseType = type.BaseType; if (baseType != null) { if (TryGetPropertyReadingField(host, baseType, field, out property)) { return(true); } } property = null; return(false); }
/// <summary> /// Given a method definition, this function gets the generic parameters /// </summary> /// <param name="type"></param> /// <returns></returns> public static TypeEx[] GetGenericMethodParameters(IPexComponent host, MethodDefinition mdef) { TypeEx[] typErr = new TypeEx[mdef.GenericMethodParametersCount]; TypeEx inttype = MetadataFromReflection.GetType(typeof(int)); int count = 0; foreach (var genp in mdef.GenericMethodParameters) { TypeEx predefTypeEx; if (PreDefinedGenericClasses.TryGetInstantiatedClass(host, genp.Name, null, out predefTypeEx)) { typErr[count] = predefTypeEx; } else { typErr[count] = inttype; } count++; } return(typErr); }
public static void ProcessStInd(Type T, StackTypes stack) { TypeEx val = stack.Pop(); TypeEx addr = stack.Pop(); if(!addr.type.IsByRef) throw new VerifierException(); TypeEx targetType = new TypeEx(addr.type.GetElementType()); TypeEx sourceType = new TypeEx(T); TypeChecker.CheckAssignment(targetType,val); CheckPrimitiveIndirectAssignment(targetType,sourceType); }
public static bool IsInt32OrCompatible(TypeEx T) { if(T.boxed) return(false); Type t = T.type; if(t == null) return(false); if(t.IsEnum) if(t.UnderlyingSystemType.IsEnum) return(true); else return(IsInt32OrCompatible(new TypeEx(t.UnderlyingSystemType))); return ( t.Equals(typeof(byte)) || t.Equals(typeof(sbyte)) || t.Equals(typeof(short)) || t.Equals(typeof(ushort)) || t.Equals(typeof(int)) || t.Equals(typeof(uint)) || t.Equals(typeof(bool)) || t.Equals(typeof(char)) ); }
/* Used by verifier to push type on the stack */ public void Push(TypeEx x) { stack.Add(x); }
public static TypeEx WeakFixType(TypeEx T) { if(T.boxed) return(T); return(new TypeEx(WeakFixType(T.type))); }
public static bool IsIntPtrOrCompatible(TypeEx T) { if(T.boxed) return(false); Type t = T.type; if(t == null) return(false); return ( t.Equals(typeof(IntPtr)) || t.Equals(typeof(UIntPtr)) ); }
public static void CheckTypes(TypeEx t1,TypeEx t2) //for CLT CLE BEQ ... { if((!t1.IsBoxable || t1.boxed) && (!t2.IsBoxable || t2.boxed)) return;//substracting object references is allowed if(!t1.boxed && !t2.boxed) GetReturnType(t1,t2,true);//Check for arguments compatibility (both Int32 || both Int64 || both IntPtr || both float ) else throw new VerifierException(); // one value is boxed and the other one is not. }
//the same as FixType, but drops `int` into `IntPtr` public static TypeEx StrongFixType(TypeEx t) { if(IsInt32OrCompatible(t)) return(new TypeEx(typeof(IntPtr))); if(IsInt64OrCompatible(t)) return(new TypeEx(typeof(long))); if(IsIntPtrOrCompatible(t)) return(new TypeEx(typeof(IntPtr))); if(IsFloatOrCompatible(t)) return(new TypeEx(typeof(double))); return(t); }
static public void ProcessLdInd(Type T, StackTypes stack) { TypeEx addr = stack.Pop(); if(!addr.type.IsByRef) throw new VerifierException(); TypeEx sourceType = new TypeEx(addr.type.GetElementType()); TypeEx targetType = new TypeEx(T); if(targetType.type.Equals(typeof(object))) //.ref suffix stack.Push(sourceType); else { TypeChecker.CheckAssignment(targetType,sourceType); stack.Push(targetType); } }
public static void ProcessRet(TypeEx returnType, StackTypes stack) { if(!returnType.type.Equals(typeof(void))) { TypeEx t = stack.Pop(); TypeChecker.CheckAssignment(returnType, t); } if(stack.Count != 0) throw new VerifierException(); }
public static void ProcessStElem(StackTypes stack, TypeEx desiredArrayElem) { TypeEx elemValue = stack.Pop(); TypeEx index = stack.Pop(); TypeEx array = stack.Pop(); TypeEx arrayElem = ProcessLdStElem(array,desiredArrayElem,index); TypeChecker.CheckAssignment(arrayElem,elemValue); }
public static void ProcessCastClass(StackTypes stack, TypeEx t) { TypeEx T = stack.Pop(); if(T.IsBoxable && !T.boxed) throw new VerifierException(); stack.Push(t); }
public static void ProcessLdElem(StackTypes stack,TypeEx desiredArrayElem,bool loadAddress) { TypeEx index = stack.Pop(); TypeEx array = stack.Pop(); TypeEx arrayElem = ProcessLdStElem(array,desiredArrayElem,index); if(loadAddress) arrayElem = arrayElem.BuildRefType(); stack.Push(arrayElem); }
private static TypeEx ProcessLdStElem(TypeEx array, TypeEx desiredArrayElem, TypeEx index) { if(!array.type.IsArray) throw new VerifierException(); if(!(TypeFixer.IsInt32OrCompatible(index) || TypeFixer.IsIntPtrOrCompatible(index))) throw new VerifierException(); TypeEx arrayElem = new TypeEx(array.type.GetElementType()); CheckPrimitiveIndirectAssignment(arrayElem,desiredArrayElem); return(arrayElem); }
private static void CheckPrimitiveIndirectAssignment(TypeEx T1,TypeEx T2) { T1 = TypeFixer.WeakFixType(T1); T2 = TypeFixer.WeakFixType(T2); Type t1 = T1.type; Type t2 = T2.type; if(t1.IsPrimitive && !t1.Equals(t2)) throw new VerifierException(); }
public static bool IsAssignable(TypeEx T1,TypeEx T2) { T1 = TypeFixer.StrongFixType(T1); T2 = TypeFixer.StrongFixType(T2);//Int32 is assignable from IntPtr and vice verce if(T1.Equals(T2)) return(true); Type t1 = T1.type; Type t2 = T2.type; //Checks if t1 is more general than t2 if(t1 == null) if(t2 == null) return(true); else return(false); if(t2 == null) //this means that t2 is actually a null reference => of any object type if(T1.IsBoxable && !T1.boxed) return(false); else return(true); //Non-boxed values must be exactly equal when assigned if(T1.IsBoxable && !T1.boxed || T2.IsBoxable && !T2.boxed) return(false); //Patching ModuleBuilder f*****g bugs :(( if(T1.type.Equals(typeof(Enum)) && T2.type.IsEnum) return(true); if(T1.type.Equals(typeof(Array)) && T2.type.IsArray) return(true); if(!T1.type.IsAssignableFrom(T2.type))//Andrew: don't know how it actually works :) return(false); return(true); }
public static void CheckBrTrueFalseType(TypeEx T) { Type t = T.type; if(t.IsByRef || t.IsEnum || t.IsPrimitive) return; //ok if(T.type.IsValueType && !T.boxed) throw new VerifierException(); }
public static void CheckAssignment(TypeEx T1,TypeEx T2) { if(! IsAssignable(T1,T2)) throw new VerifierException(); }
public static TypeEx MergeTypes(TypeEx T1,TypeEx T2) { Type t1 = T1.type; Type t2 = T2.type; if(t1 == null && t2 == null) return(new TypeEx(null)); if(t2 == null) if(T1.IsBoxable && !T1.boxed) throw new VerifierException(); else return(T1); if(t1 == null) if(T2.IsBoxable && !T2.boxed) throw new VerifierException(); else return(T2); TypeEx T = DoMergeTypes(T1,T2); if(T.type == null) throw new VerifierException(); return(T); }
public static TypeEx GetReturnType(TypeEx t1,TypeEx t2,bool isFloatOperation) { if(IsInt32OrCompatible(t1) && IsInt32OrCompatible(t2)) return(new TypeEx(typeof(int))); if(IsInt64OrCompatible(t1) && IsInt64OrCompatible(t2)) return(new TypeEx(typeof(long))); if((IsIntPtrOrCompatible(t1) || IsInt32OrCompatible(t1)) && (IsIntPtrOrCompatible(t2) || IsInt32OrCompatible(t2))) return(new TypeEx(typeof(IntPtr))); if(isFloatOperation) if(IsFloatOrCompatible(t1) && IsFloatOrCompatible(t2)) return(new TypeEx(typeof(double))); throw new VerifierException(); //incompatible operands }
private static TypeEx DoMergeTypes(TypeEx T1,TypeEx T2) { //returns t that is more general than t1, t2 T1 = FixType(T1); T2 = FixType(T2); if(T1.Equals(T2)) return(T1); //in the sequel T1 != T2 Type t1 = T1.type; Type t2 = T2.type; if(T1.IsBoxable && !T1.boxed) { if(T2.boxed) throw new VerifierException(); //mb Int32 and IntPtr ? if( (t1.Equals(typeof(int)) || t1.Equals(typeof(IntPtr))) && (t2.Equals(typeof(int)) || t2.Equals(typeof(IntPtr))) ) return(new TypeEx(typeof(IntPtr))); else throw new VerifierException(); } if(t1.IsByRef) //Should be exactly equal throw new VerifierException(); if(t1.IsArray && t2.IsArray) { Type t1Elem = t1.GetElementType(); Type t2Elem = t2.GetElementType(); if(t1Elem.IsValueType || t2Elem.IsValueType) return(new TypeEx(typeof(Array))); TypeEx T = DoMergeTypes(new TypeEx(t1Elem) , new TypeEx(t2Elem)); return(T.BuildArrayType()); //Andrew!! may fail when working with ModuleBuilder } if(t1.IsInterface || t2.IsInterface) return(DoMergeInterfaces(T1,T2)); return(DoMergeClasses(T1,T2)); }
public static TypeEx FixType(TypeEx t) { if(IsInt32OrCompatible(t)) return(new TypeEx(typeof(int))); if(IsInt64OrCompatible(t)) return(new TypeEx(typeof(long))); if(IsIntPtrOrCompatible(t)) return(new TypeEx(typeof(IntPtr)));//typeof(int)? //PEVerify doesn't make difference between "int32" and "native int"... if(IsFloatOrCompatible(t)) return(new TypeEx(typeof(double))); return(t); }
private static TypeEx DoMergeInterfaces(TypeEx t1, TypeEx t2) { return(FindCommonInterface( GetInterfaces(t1), GetInterfaces(t2) )); }
public static bool IsFloatOrCompatible(TypeEx T) { if(T.boxed) return(false); Type t = T.type; if(t == null) return(false); return ( t.Equals(typeof(float)) || t.Equals(typeof(double)) ); }
private static Type[] GetInterfaces(TypeEx T) { Type t = T.type; if(t.IsClass || T.boxed) return(t.GetInterfaces()); if(! t.IsInterface) throw new VerifierException(); //t.IsInterface Type[] _ifaces_ = t.GetInterfaces(); Type[] ifaces = new Type[_ifaces_.Length + 1]; ifaces[0] = t; _ifaces_.CopyTo(ifaces,1); return(ifaces); }
public static bool IsInt64OrCompatible(TypeEx T) { if(T.boxed) return(false); Type t = T.type; if(t == null) return(false); if(t.IsEnum) if(t.UnderlyingSystemType.IsEnum) //supposed int32 return(false); else return(IsInt64OrCompatible(new TypeEx(t.UnderlyingSystemType))); return ( t.Equals(typeof(long)) || t.Equals(typeof(ulong)) ); }
private static TypeEx DoMergeClasses(TypeEx t1,TypeEx t2) { ArrayList ps1 = GetParents(t1); //t1 parents ArrayList ps2 = GetParents(t2); //t2 parents int i = 1; //ps1[0] == ps2[0] == typeof(object) for(; i<ps1.Count && i<ps2.Count ;i++) if(! Equals(ps1[i],ps2[i])) break; return(new TypeEx(ps1[i-1] as Type , true)); }
internal static bool Check(MethodEx methodRepr) { //Attention: the `null` value on stack means a null reference that is of any object type //As `typeof(object)` is the most general Type, so `null` is the most exact object type FreeStacks(methodRepr); try { Instruction lastI = methodRepr[methodRepr.Count-1]; if( lastI.Code != InstructionCode.RET && lastI.Code != InstructionCode.BR && lastI.Code != InstructionCode.THROW && lastI.Code != InstructionCode.RETHROW && lastI.Code != InstructionCode.LEAVE && lastI.Code != InstructionCode.ENDFINALLY && lastI.Code != InstructionCode.ENDFILTER ) throw new VerifierException(); MethodInfoExtention method = new MethodInfoExtention(methodRepr.Method); StackTypes stack = new StackTypes(); //initially the stack is empty int nextHandler = FindNextHandler(-1,methodRepr.EHClauses); CheckBlockExits(methodRepr); for (int iNum = 0; iNum < methodRepr.Count ; iNum ++) { Instruction i = methodRepr[iNum]; i.SetStack(MergeStacks(i.Stack,stack)); if(nextHandler == iNum) { PushExceptionOnStack(iNum,i.Stack,methodRepr.EHClauses); nextHandler = FindNextHandler(iNum,methodRepr.EHClauses); } stack = i.Stack.Clone() as StackTypes; switch(i.Code) { case InstructionCode.DUP : { stack.Push(stack.Peek()); } break; case InstructionCode.LDARG : { stack.Push(method.GetArgType((Int32)i.Param)); } break; case InstructionCode.LDARGA : { TypeEx t = method.GetArgType((Int32)i.Param).BuildRefType(); stack.Push(t); } break; case InstructionCode.LDLOCA : { TypeEx t = new TypeEx(TypeEx.BuildRefType(methodRepr.Locals[(Int32)i.Param])); stack.Push(t); } break; case InstructionCode.LDLOC : { stack.Push(new TypeEx(methodRepr.Locals[(Int32)i.Param])); } break; case InstructionCode.LDIND : { ProcessLdInd(i.TypeBySuffixOrParam(), stack); } break; case InstructionCode.LDC: { stack.Push(new TypeEx(i.TypeBySuffixOrParam())); } break; case InstructionCode.LDNULL: { stack.Push(new TypeEx(null));//see `Attention` at the top of the method. } break; case InstructionCode.LDFLD: { ProcessLdFld(stack, i.Param as FieldInfo,false); } break; case InstructionCode.LDFLDA: { ProcessLdFld(stack, i.Param as FieldInfo,true); } break; case InstructionCode.LDSFLD: { stack.Push(new TypeEx((i.Param as FieldInfo).FieldType)); } break; case InstructionCode.LDSFLDA: { stack.Push(TypeEx.BuildRefType((i.Param as FieldInfo).FieldType)); } break; case InstructionCode.LDELEM: { ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), false); } break; case InstructionCode.LDELEMA: { ProcessLdElem(stack, new TypeEx(i.TypeBySuffixOrParam()), true); } break; case InstructionCode.LDLEN : { ProcessLdLen(stack); } break; case InstructionCode.LDOBJ : { ProcessLdObj(stack, i.Param as Type); } break; case InstructionCode.LDSTR: { if(!(i.Param is string)) throw new VerifierException(); stack.Push(typeof(string)); } break; case InstructionCode.LDFTN: { stack.Push(new TypeEx(typeof(IntPtr))); } break; case InstructionCode.LDVIRTFTN: { TypeEx obj = stack.Pop(); MethodInfo methodInfo = i.Param as MethodInfo; if(!methodInfo.IsVirtual) throw new VerifierException(); TypeChecker.CheckAssignment(new TypeEx(methodInfo.DeclaringType , true), obj); stack.Push(typeof(IntPtr)); } break; case InstructionCode.LDTOKEN: { if(i.Param is Type) stack.Push(typeof(System.RuntimeTypeHandle)); else if(i.Param is MethodBase) stack.Push(typeof(System.RuntimeMethodHandle)); else if(i.Param is FieldInfo) stack.Push(typeof(System.RuntimeFieldHandle)); else throw new VerifierException(); } break; case InstructionCode.SIZEOF : { ProcessSizeOf(stack,i.Param as Type); } break; case InstructionCode.CLT: case InstructionCode.CGT: case InstructionCode.CEQ: { ProcessBinOp(OpType.Compare,stack); } break; case InstructionCode.BLE: case InstructionCode.BLT: case InstructionCode.BGE: case InstructionCode.BGT: case InstructionCode.BEQ: case InstructionCode.BNE: { TypeEx t1 = stack.Pop(); TypeEx t2 = stack.Pop(); Arithmetics.CheckTypes(t1,t2); ProcessBr(iNum,methodRepr,stack); stack = stack.Clone() as StackTypes; //Andrew: mb wrong, we may let equal stacks to be the same object } break; case InstructionCode.BRTRUE: case InstructionCode.BRFALSE: { ProcessBrTrueFalse(stack); ProcessBr(iNum,methodRepr,stack); stack = stack.Clone() as StackTypes; //Andrew: mb wrong, we may let equal stacks to be the same object } break; case InstructionCode.BR : { ProcessBr(iNum,methodRepr,stack); stack = null; } break; case InstructionCode.SWITCH: { ProcessSwitch(stack); ProcessSwitch(iNum,methodRepr,stack); stack = stack.Clone() as StackTypes; } break; case InstructionCode.THROW : { ProcessThrow(stack); stack = null; }break; case InstructionCode.RETHROW : { if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Catch) throw new VerifierException(); stack = null; }break; case InstructionCode.LEAVE : { BlockType blockType = GetNearestBlock(methodRepr.EHClauses,iNum).type; if(blockType != BlockType.Catch && blockType != BlockType.Try) throw new VerifierException(); ProcessLeave(iNum,methodRepr,stack); stack = null; } break; case InstructionCode.ENDFINALLY : { if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Finally) throw new VerifierException(); ProcessLeave(stack); stack = null; } break; case InstructionCode.ENDFILTER : { if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Filter) throw new VerifierException(); ProcessEndFilter(stack); stack = null; } break; case InstructionCode.NOT: { ProcessNot(stack); } break; case InstructionCode.NEG: { ProcessNeg(stack); } break; case InstructionCode.CKFINITE : { ProcessCkFinite(stack); } break; case InstructionCode.CONV: { ProcessConv(i.TypeBySuffixOrParam(), stack); } break; case InstructionCode.SUB: case InstructionCode.ADD: case InstructionCode.MUL: case InstructionCode.DIV: case InstructionCode.REM: case InstructionCode.XOR: case InstructionCode.OR: case InstructionCode.AND: { ProcessBinOp(IsFloatOperation(i) ? OpType.FloatOrInt : OpType.Int , stack); } break; case InstructionCode.SHL: case InstructionCode.SHR: { ProcessBinOp(OpType.Shift , stack); } break; case InstructionCode.CPOBJ : { ProcessCpObj(stack, i.Param as Type); } break; case InstructionCode.STARG : { ProcessSt(method.GetArgType((Int32)i.Param) , stack); } break; case InstructionCode.STLOC : { ProcessSt(new TypeEx(methodRepr.Locals[(Int32)i.Param]) , stack); } break; case InstructionCode.STIND : { ProcessStInd(i.TypeBySuffixOrParam() , stack); } break; case InstructionCode.STFLD: { ProcessStFld(stack, i.Param as FieldInfo); } break; case InstructionCode.STSFLD: { ProcessStSFld(stack, i.Param as FieldInfo); } break; case InstructionCode.STELEM: { ProcessStElem(stack, new TypeEx(i.TypeBySuffixOrParam())); } break; case InstructionCode.STOBJ : { ProcessStObj(stack, i.Param as Type); } break; case InstructionCode.RET : { if(GetNearestBlock(methodRepr.EHClauses,iNum).type != BlockType.Global) throw new VerifierException(); ProcessRet(method.GetReturnType(), stack); stack = null; } break; case InstructionCode.CALL : case InstructionCode.CALLVIRT : case InstructionCode.NEWOBJ : { //constructor may be invoked using either CALL or NEWOBJ instructions MethodBase callee = i.Param as MethodBase; if(i.Code == InstructionCode.NEWOBJ && callee.IsConstructor && IsDelegate(callee.DeclaringType)) ProcessDelegateConstruction(methodRepr,iNum,stack); else ProcessCallOrNewobj(new MethodInfoExtention(callee,i.Code == InstructionCode.CALLVIRT), stack, i.Code == InstructionCode.NEWOBJ); if(i.HasTail && methodRepr[iNum+1].Code != InstructionCode.RET) throw new VerifierException(); } break; case InstructionCode.INITOBJ : { ProcessInitObj(stack, i.Param as Type); } break; case InstructionCode.NEWARR : { ProcessNewArr(stack, i.Param as Type); } break; case InstructionCode.ISINST : case InstructionCode.CASTCLASS : { ProcessCastClass(stack, new TypeEx(i.Param as Type , true)); } break; case InstructionCode.BOX : { ProcessBox(stack, i.Param as Type); } break; case InstructionCode.UNBOX : { ProcessUnBox(stack, i.Param as Type); } break; case InstructionCode.POP : { stack.Pop(); } break; case InstructionCode.NOP : case InstructionCode.BREAK : break; default: { throw new VerifierException(); //Instruction is not supported yet... } } } return(true); } catch(VerifierException ) { FreeStacks(methodRepr); return(false); } //catch(NullReferenceException ) //Andrew: ZaLyaPa :( waiting for Sergey to patch NEWOBJ (delegate construction) //{ // FreeStacks(methodRepr); // return(false); //} }
private static ArrayList GetParents(TypeEx T) { Type t = T.type; if(!t.IsClass && !T.boxed) throw new VerifierException(); ArrayList ps = new ArrayList(); for(; t!=null ; t=t.BaseType) ps.Add(t); ps.Reverse(); return(ps); }
public static void ProcessSt(TypeEx T, StackTypes stack) { TypeEx t = stack.Pop(); TypeChecker.CheckAssignment(T,t); }
private Type VarType(TypeEx typeEx) { return(typeEx.boxed ? typeof(object) : typeEx.type); }