Ejemplo n.º 1
0
        public TypeData this[uint idx]
        {
            get
            {
                return m_array[idx];
            }

            set
            {
                lock (m_writeLock)
                {
                    Debug.Assert(value.TypeID == idx);

                    if (idx >= m_array.Length)
                    {
                        var newArray = new TypeData[NextPowOf2(idx + 1)];
                        Array.Copy(m_array, newArray, m_array.Length);
                        m_array = newArray;
                    }

                    Debug.Assert(m_array[idx] == null);

                    m_array[idx] = value;
                }
            }
        }
Ejemplo n.º 2
0
		public bool TryGetValue(Type key, out TypeData value)
		{
			var buckets = Volatile.Read(ref m_buckets);

			int idx = Hash(key, buckets.Length);

			Pair[] arr = Volatile.Read(ref buckets[idx]);
			if (arr == null)
				goto not_found;

			for (int i = 0; i < arr.Length; ++i)
			{
				if (arr[i].Key == key)
				{
					value = arr[i].Value;
					return true;
				}
			}

			not_found:
			value = null;
			return false;
		}
Ejemplo n.º 3
0
        public static void GenerateDeserializerTrampoline(ILGenerator il, Type type, TypeData data)
        {
            if (type.IsValueType)
            {
                var local = il.DeclareLocal(type);

                // call deserializer for this typeID
                if (data.NeedsInstanceParameter)
                    il.Emit(OpCodes.Ldarg_0);

                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldloca_S, local);

                il.Emit(OpCodes.Call, data.ReaderMethodInfo);

                // write result object to out object
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Box, type);
                il.Emit(OpCodes.Stind_Ref);
            }
            else
            {
                // call deserializer for this typeID
                if (data.NeedsInstanceParameter)
                    il.Emit(OpCodes.Ldarg_0);

                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);

                il.Emit(OpCodes.Tailcall);
                il.Emit(OpCodes.Call, data.ReaderMethodInfo);
            }

            il.Emit(OpCodes.Ret);
        }
Ejemplo n.º 4
0
        static Dictionary<Type, TypeData> GenerateTypeData(Type[] types)
        {
            var map = new Dictionary<Type, TypeData>(types.Length);

            // TypeID 0 is reserved for null
            #if GENERATE_SWITCH
            ushort caseID = (ushort)(s_Type_caseIDtypeIDMap == null ? 1 : s_Type_caseIDtypeIDMap.Count + 1);
            #endif
            foreach (var type in types)
            {
                ushort typeID;
                if (!SerializationID.predefinedID.TryGetValue(type, out typeID))
                {
                    typeID = SerializationID.userID++;
                }

                MethodInfo writer;
                MethodInfo reader;

                bool isStatic = Helpers.GetPrimitives(typeof(Primitives), type, out writer, out reader);

                if (type.IsPrimitive && isStatic == false)
                    throw new InvalidOperationException(String.Format("Missing primitive read/write methods for {0}", type.FullName));

            #if GENERATE_SWITCH
                var td = new TypeData(typeID, caseID++);
            #else
                var td = new TypeData(typeID);
            #endif
                if (isStatic)
                {
                    if (writer.IsGenericMethodDefinition)
                    {
                        Debug.Assert(type.IsGenericType);

                        var genArgs = type.GetGenericArguments();

                        writer = writer.MakeGenericMethod(genArgs);
                        reader = reader.MakeGenericMethod(genArgs);
                    }

                    td.WriterMethodInfo = writer;
                    td.ReaderMethodInfo = reader;
                    td.IsDynamic = false;
                }
                else
                {
                    if (typeof(System.Runtime.Serialization.ISerializable).IsAssignableFrom(type))
                        throw new InvalidOperationException(String.Format("Cannot serialize {0}: ISerializable not supported", type.FullName));

                    td.IsDynamic = true;
                }

                map[type] = td;
            }

            return map;
        }
Ejemplo n.º 5
0
		static Dictionary<Type, TypeData> GenerateTypeData(Type[] rootTypes)
		{
			var map = new Dictionary<Type, TypeData>();
			var stack = new Stack<Type>(PrimitivesSerializer.GetSupportedTypes().Concat(rootTypes));

			// TypeID 0 is reserved for null
			ushort typeID = 1;

			while (stack.Count > 0)
			{
				var type = stack.Pop();

				if (map.ContainsKey(type))
					continue;

				if (type.IsAbstract || type.IsInterface)
					continue;

				if (type.ContainsGenericParameters)
					throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));

				var serializer = s_userTypeSerializers.FirstOrDefault(h => h.Handles(type));

				if (serializer == null)
					serializer = s_typeSerializers.FirstOrDefault(h => h.Handles(type));

				if (serializer == null)
					throw new NotSupportedException(String.Format("No serializer for {0}", type.FullName));

				foreach (var t in serializer.GetSubtypes(type))
					stack.Push(t);

				TypeData typeData;

				if (serializer is IStaticTypeSerializer)
				{
					var sts = (IStaticTypeSerializer)serializer;

					MethodInfo writer;
					MethodInfo reader;

					sts.GetStaticMethods(type, out writer, out reader);

					Debug.Assert(writer != null && reader != null);

					typeData = new TypeData(typeID++, writer, reader);

				}
				else if (serializer is IDynamicTypeSerializer)
				{
					var dts = (IDynamicTypeSerializer)serializer;

					typeData = new TypeData(typeID++, dts);
				}
				else
				{
					throw new Exception();
				}

				map[type] = typeData;
			}

			return map;
		}
Ejemplo n.º 6
0
        /// <summary>
        /// Create delegate that calls reader either directly, or via a trampoline
        /// </summary>
        public static Delegate CreateDeserializeDelegate(Type paramType, TypeData data)
        {
            Type readerType = data.Type;

            if (paramType != readerType && paramType != typeof(object))
            {
                throw new Exception();
            }

            bool needTypeConv           = paramType != readerType;
            bool needsInstanceParameter = data.ReaderNeedsInstance;

            var delegateType = typeof(DeserializeDelegate <>).MakeGenericType(paramType);

            // Can we call the reader directly?

            if (!needTypeConv && needsInstanceParameter)
            {
                if (data.ReaderMethodInfo is DynamicMethod dynamicReader)
                {
                    return(dynamicReader.CreateDelegate(delegateType));
                }
                else
                {
                    return(Delegate.CreateDelegate(delegateType, data.ReaderMethodInfo));
                }
            }

            // Create a trampoline

            var wrapper = GenerateDynamicDeserializerStub(paramType);
            var il      = wrapper.GetILGenerator();

            if (needsInstanceParameter)
            {
                il.Emit(OpCodes.Ldarg_0);
            }

            if (needTypeConv && readerType.IsValueType)
            {
                var local = il.DeclareLocal(readerType);

                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldloca_S, local);

                il.Emit(OpCodes.Call, data.ReaderMethodInfo);

                // write result object to out object
                il.Emit(OpCodes.Ldarg_2);
                il.Emit(OpCodes.Ldloc_0);
                il.Emit(OpCodes.Box, readerType);
                il.Emit(OpCodes.Stind_Ref);
            }
            else
            {
                il.Emit(OpCodes.Ldarg_1);
                il.Emit(OpCodes.Ldarg_2);

                // XXX tailcall causes slowdowns with large valuetypes
                //il.Emit(OpCodes.Tailcall);
                il.Emit(OpCodes.Call, data.ReaderMethodInfo);
            }

            il.Emit(OpCodes.Ret);

            return(wrapper.CreateDelegate(delegateType));
        }
Ejemplo n.º 7
0
 public Pair(Type key, TypeData value)
 {
     this.Key   = key;
     this.Value = value;
 }
Ejemplo n.º 8
0
 public Pair(Type key, TypeData value)
 {
     this.Key = key;
     this.Value = value;
 }
Ejemplo n.º 9
0
        static void Add(Pair[][] buckets, Type key, TypeData value)
        {
            int idx = Hash(key, buckets.Length);

            Pair[] arr = buckets[idx];
            if (arr == null)
                buckets[idx] = arr = new Pair[InitialListSize];

            for (int i = 0; i < arr.Length; ++i)
            {
                if (arr[i].Key == null)
                {
                    arr[i] = new Pair(key, value);
                    return;
                }
            }

            var newArr = new Pair[arr.Length * 2];
            Array.Copy(arr, newArr, arr.Length);
            newArr[arr.Length] = new Pair(key, value);
            buckets[idx] = newArr;
        }
Ejemplo n.º 10
0
		/// <summary>
		/// Create delegate that calls reader either directly, or via a trampoline
		/// </summary>
		public static Delegate CreateDeserializeDelegate(Type paramType, TypeData data)
		{
			Type readerType = data.Type;

			if (paramType != readerType && paramType != typeof(object))
				throw new Exception();

			bool needTypeConv = paramType != readerType;
			bool needsInstanceParameter = data.ReaderNeedsInstance;

			var delegateType = typeof(DeserializeDelegate<>).MakeGenericType(paramType);

			// Can we call the reader directly?

			if (!needTypeConv && needsInstanceParameter)
			{
				var dynamicReader = data.ReaderMethodInfo as DynamicMethod;

				if (dynamicReader != null)
					return dynamicReader.CreateDelegate(delegateType);
				else
					return Delegate.CreateDelegate(delegateType, data.ReaderMethodInfo);
			}

			// Create a trampoline

			var wrapper = GenerateDynamicDeserializerStub(paramType);
			var il = wrapper.GetILGenerator();

			if (needsInstanceParameter)
				il.Emit(OpCodes.Ldarg_0);

			if (needTypeConv && readerType.IsValueType)
			{
				var local = il.DeclareLocal(readerType);

				il.Emit(OpCodes.Ldarg_1);
				il.Emit(OpCodes.Ldloca_S, local);

				il.Emit(OpCodes.Call, data.ReaderMethodInfo);

				// write result object to out object
				il.Emit(OpCodes.Ldarg_2);
				il.Emit(OpCodes.Ldloc_0);
				il.Emit(OpCodes.Box, readerType);
				il.Emit(OpCodes.Stind_Ref);
			}
			else
			{
				il.Emit(OpCodes.Ldarg_1);
				il.Emit(OpCodes.Ldarg_2);

				// XXX tailcall causes slowdowns with large valuetypes
				//il.Emit(OpCodes.Tailcall);
				il.Emit(OpCodes.Call, data.ReaderMethodInfo);
			}

			il.Emit(OpCodes.Ret);

			return wrapper.CreateDelegate(delegateType);
		}
Ejemplo n.º 11
0
        void AddTypesInternal(Dictionary <Type, uint> typeMap)
        {
            AssertLocked();

            foreach (var kvp in typeMap)
            {
                var  type   = kvp.Key;
                uint typeID = kvp.Value;

                if (type == null)
                {
                    throw new ArgumentException("Null type in dictionary");
                }

                if (typeID == 0)
                {
                    throw new ArgumentException("TypeID 0 is reserved");
                }

                if (m_runtimeTypeMap.ContainsKey(type))
                {
                    if (m_runtimeTypeMap[type].TypeID != typeID)
                    {
                        throw new ArgumentException(String.Format("Type {0} already added with different TypeID", type.FullName));
                    }

                    continue;
                }

                if (m_runtimeTypeIDList.ContainsTypeID(typeID))
                {
                    throw new ArgumentException(String.Format("Type with typeID {0} already added", typeID));
                }
#if !NET35 && !NET40
                if (type.GetTypeInfo().IsAbstract || type.GetTypeInfo().IsInterface)
                {
                    throw new ArgumentException(String.Format("Type {0} is abstract or interface", type.FullName));
                }

                if (type.GetTypeInfo().ContainsGenericParameters)
                {
                    throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));
                }
#else
                if (type.IsAbstract || type.IsInterface)
                {
                    throw new ArgumentException(String.Format("Type {0} is abstract or interface", type.FullName));
                }

                if (type.ContainsGenericParameters)
                {
                    throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));
                }
#endif
                ITypeSerializer serializer = GetTypeSerializer(type);

                var data = new TypeData(type, typeID, serializer);
                m_runtimeTypeMap[type]      = data;
                m_runtimeTypeIDList[typeID] = data;
            }
        }
Ejemplo n.º 12
0
        Dictionary <Type, uint> AddTypesInternal(IEnumerable <Type> roots)
        {
            AssertLocked();

            var stack    = new Stack <Type>(roots);
            var addedMap = new Dictionary <Type, uint>();

            while (stack.Count > 0)
            {
                var type = stack.Pop();

                if (m_runtimeTypeMap.ContainsKey(type))
                {
                    continue;
                }
#if !NET35 && !NET40
                if (type.GetTypeInfo().IsAbstract || type.GetTypeInfo().IsInterface)
                {
                    continue;
                }

                if (type.GetTypeInfo().ContainsGenericParameters)
                {
                    throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));
                }
#else
                if (type.IsAbstract || type.IsInterface)
                {
                    continue;
                }

                if (type.ContainsGenericParameters)
                {
                    throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));
                }
#endif
                while (m_runtimeTypeIDList.ContainsTypeID(m_nextAvailableTypeID))
                {
                    m_nextAvailableTypeID++;
                }

                uint typeID = m_nextAvailableTypeID++;

                ITypeSerializer serializer = GetTypeSerializer(type);

                var data = new TypeData(type, typeID, serializer);
                m_runtimeTypeMap[type]      = data;
                m_runtimeTypeIDList[typeID] = data;

                addedMap[type] = typeID;

                foreach (var t in serializer.GetSubtypes(type))
                {
                    if (m_runtimeTypeMap.ContainsKey(t) == false)
                    {
                        stack.Push(t);
                    }
                }
            }

            return(addedMap);
        }
Ejemplo n.º 13
0
        public static void GenerateSerializerTrampoline(ILGenerator il, Type type, TypeData data)
        {
            if (data.NeedsInstanceParameter)
                il.Emit(OpCodes.Ldarg_0);

            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(type.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, type);

            il.Emit(OpCodes.Tailcall);
            il.Emit(OpCodes.Call, data.WriterMethodInfo);

            il.Emit(OpCodes.Ret);
        }
Ejemplo n.º 14
0
		/// <summary>
		/// Create delegate that calls writer either directly, or via a trampoline
		/// </summary>
		public static Delegate CreateSerializeDelegate(Type paramType, TypeData data)
		{
			Type writerType = data.Type;

			if (paramType != writerType && paramType != typeof(object))
				throw new Exception();

			bool needTypeConv = paramType != writerType;
			bool needsInstanceParameter = data.WriterNeedsInstance;

			var delegateType = typeof(SerializeDelegate<>).MakeGenericType(paramType);

			// Can we call the writer directly?

			if (!needTypeConv && needsInstanceParameter)
			{
				var dynamicWriter = data.WriterMethodInfo as DynamicMethod;

				if (dynamicWriter != null)
					return dynamicWriter.CreateDelegate(delegateType);
				else
					return Delegate.CreateDelegate(delegateType, data.WriterMethodInfo);
			}

			// Create a trampoline

			var wrapper = Helpers.GenerateDynamicSerializerStub(paramType);
			var il = wrapper.GetILGenerator();

			if (needsInstanceParameter)
				il.Emit(OpCodes.Ldarg_0);

			il.Emit(OpCodes.Ldarg_1);
			il.Emit(OpCodes.Ldarg_2);
			if (needTypeConv)
				il.Emit(writerType.IsValueType ? OpCodes.Unbox_Any : OpCodes.Castclass, writerType);

			// XXX tailcall causes slowdowns with large valuetypes
			//il.Emit(OpCodes.Tailcall);
			il.Emit(OpCodes.Call, data.WriterMethodInfo);

			il.Emit(OpCodes.Ret);

			return wrapper.CreateDelegate(delegateType);
		}
Ejemplo n.º 15
0
        static Dictionary<Type, TypeData> GenerateTypeData(Type[] types)
        {
            var map = new Dictionary<Type, TypeData>(types.Length);

            // TypeID 0 is reserved for null
            ushort typeID = 1;
            foreach (var type in types)
            {
                MethodInfo writer;
                MethodInfo reader;

                bool isStatic = Helpers.GetPrimitives(typeof(Primitives), type, out writer, out reader);

                if (type.IsPrimitive && isStatic == false)
                    throw new InvalidOperationException(String.Format("Missing primitive read/write methods for {0}", type.FullName));

                var td = new TypeData(typeID++);

                if (isStatic)
                {
                    if (writer.IsGenericMethodDefinition)
                    {
                        Debug.Assert(type.IsGenericType);

                        var genArgs = type.GetGenericArguments();

                        writer = writer.MakeGenericMethod(genArgs);
                        reader = reader.MakeGenericMethod(genArgs);
                    }

                    td.WriterMethodInfo = writer;
                    td.ReaderMethodInfo = reader;
                    td.IsDynamic = false;
                }
                else
                {
                    if (typeof(System.Runtime.Serialization.ISerializable).IsAssignableFrom(type))
                        throw new InvalidOperationException(String.Format("Cannot serialize {0}: ISerializable not supported", type.FullName));

                    td.IsDynamic = true;
                }

                map[type] = td;
            }

            return map;
        }
Ejemplo n.º 16
0
        static Dictionary<Type, TypeData> GenerateTypeData(Type[] types)
        {
            var map = new Dictionary<Type, TypeData>(types.Length);

            // TypeID 0 is reserved for null
            ushort typeID = 1;
            foreach (var type in types)
            {
                var writer = Primitives.GetWritePrimitive(type);
                var reader = Primitives.GetReadPrimitive(type);

                if ((writer != null) != (reader != null))
                    throw new InvalidOperationException(String.Format("Missing a read or write primitive for {0}", type.FullName));

                var isStatic = writer != null;

                if (type.IsPrimitive && isStatic == false)
                    throw new InvalidOperationException(String.Format("Missing primitive read/write methods for {0}", type.FullName));

                var td = new TypeData(typeID++);

                if (isStatic)
                {
                    td.WriterMethodInfo = writer;
                    td.ReaderMethodInfo = reader;
                    td.IsDynamic = false;
                }
                else
                {
                    if (typeof(System.Runtime.Serialization.ISerializable).IsAssignableFrom(type))
                        throw new InvalidOperationException(String.Format("Cannot serialize {0}: ISerializable not supported", type.FullName));

                    td.IsDynamic = true;
                }

                map[type] = td;
            }

            return map;
        }
Ejemplo n.º 17
0
        static Dictionary <Type, TypeData> GenerateTypeData(IEnumerable <Type> rootTypes)
        {
            var map   = new Dictionary <Type, TypeData>();
            var stack = new Stack <Type>(PrimitivesSerializer.GetSupportedTypes().Concat(rootTypes));

            // TypeID 0 is reserved for null
            ushort typeID = 1;

            while (stack.Count > 0)
            {
                var type = stack.Pop();

                if (map.ContainsKey(type))
                {
                    continue;
                }

                if (type.IsAbstract || type.IsInterface)
                {
                    continue;
                }

                if (type.ContainsGenericParameters)
                {
                    throw new NotSupportedException(String.Format("Type {0} contains generic parameters", type.FullName));
                }

                var serializer = s_userTypeSerializers.FirstOrDefault(h => h.Handles(type));

                if (serializer == null)
                {
                    serializer = s_typeSerializers.FirstOrDefault(h => h.Handles(type));
                }

                if (serializer == null)
                {
                    throw new NotSupportedException(String.Format("No serializer for {0}", type.FullName));
                }

                foreach (var t in serializer.GetSubtypes(type))
                {
                    stack.Push(t);
                }

                TypeData typeData;

                if (serializer is IStaticTypeSerializer)
                {
                    var sts = (IStaticTypeSerializer)serializer;

                    MethodInfo writer;
                    MethodInfo reader;

                    sts.GetStaticMethods(type, out writer, out reader);

                    Debug.Assert(writer != null && reader != null);

                    typeData = new TypeData(typeID++, writer, reader);
                }
                else if (serializer is IDynamicTypeSerializer)
                {
                    var dts = (IDynamicTypeSerializer)serializer;

                    typeData = new TypeData(typeID++, dts);
                }
                else
                {
                    throw new Exception();
                }

                map[type] = typeData;
            }

            return(map);
        }