示例#1
0
        public static Type Compile(Type payloadType, ref JsonSerializerOptions options)
        {
            if (options == null)
            {
                options = DefaultSerializerOptions;
            }

            TypeBuilder tb = JitAssembly.JitModuleBuilder.DefineType(
                name: JitAssembly.GeneratedModuleNamespace + @".ObjectSerialier" + Interlocked.Increment(ref _compiledCount),
                attr: TypeAttributes.Public | TypeAttributes.Sealed,
                parent: typeof(ValueType),
                interfaces: new Type[] { typeof(ISerialierImplementation <>).MakeGenericType(payloadType) }
                );

            JitILCompiler compiler = new JitILCompiler(payloadType, options, tb);

            // Compile the non chunk routine first since the chunk routine needs to know the number of labels.
            compiler.GenerateNonChunkMethod();
            compiler.GenerateChunkMethod();
            compiler.GenerateResetMethod();

            Type compiledSerializerType = tb.CreateType();

            compiler._followUp(compiledSerializerType);

            return(compiledSerializerType);
        }
示例#2
0
            public EnumerableInfo(ref JitILCompiler compiler, Type type, Type enumerateeType)
            {
                Type iCollectionType   = typeof(ICollection <>).MakeGenericType(enumerateeType);
                Type iEnumerableType   = typeof(IEnumerable <>).MakeGenericType(enumerateeType);
                Type iEnumeratorType   = typeof(IEnumerator <>).MakeGenericType(enumerateeType);
                Type iReadOnlyListType = typeof(IReadOnlyList <>).MakeGenericType(enumerateeType);
                Type iListType         = typeof(IList <>).MakeGenericType(enumerateeType);

                GetEnumeratorMethod    = null;
                GetCurrentMethod       = null;
                EnumeratorType         = null;
                GetCountMethod         = null;
                IndexAccessorMethod    = null;
                EnumerableContextField = null;

                MethodInfo nonvirtualGetEnumeratorMethod = type.GetMethod(
                    name: "GetEnumerator",
                    types: new Type[] { },
                    modifiers: null,
                    bindingAttr: BindingFlags.Public | BindingFlags.Instance,
                    binder: null
                    );

                if (type.IsArray)
                {
                    EnumeratorCategory     = EnumeratorCategory.Array;
                    EnumerableContextField = compiler.GetEnumeratorContextFieldAtIndex(compiler._enumerableContextFieldCount++, typeof(int));
                }
                else if (iReadOnlyListType.IsAssignableFrom(type) || iListType.IsAssignableFrom(type))
                {
                    EnumeratorCategory     = EnumeratorCategory.List;
                    EnumerableContextField = compiler.GetEnumeratorContextFieldAtIndex(compiler._enumerableContextFieldCount++, typeof(int));
                    Type ListInterfaceType = iReadOnlyListType.IsAssignableFrom(type) ? iReadOnlyListType : iListType;
                    GetCountMethod = GetInterfaceMethodImplementation(type, iCollectionType.GetProperty("Count").GetMethod);
                    foreach (PropertyInfo property in ListInterfaceType.GetProperties())
                    {
                        if (property.GetIndexParameters().Length == 1)
                        {
                            IndexAccessorMethod = GetInterfaceMethodImplementation(type, property.GetMethod);
                            break;
                        }
                    }
                }
                else if (nonvirtualGetEnumeratorMethod != null &&
                         iEnumeratorType.IsAssignableFrom(nonvirtualGetEnumeratorMethod.ReturnType) &&
                         nonvirtualGetEnumeratorMethod.ReturnType.IsValueType)
                {
                    EnumeratorCategory     = EnumeratorCategory.ValueTypeEnumerator;
                    GetEnumeratorMethod    = nonvirtualGetEnumeratorMethod;
                    EnumeratorType         = nonvirtualGetEnumeratorMethod.ReturnType;
                    GetCurrentMethod       = GetInterfaceMethodImplementation(EnumeratorType, iEnumeratorType.GetProperty("Current").GetMethod);
                    EnumerableContextField = compiler.GetEnumeratorContextFieldAtIndex(compiler._enumerableContextFieldCount++, EnumeratorType);
                }
                else
                {
                    EnumeratorCategory  = EnumeratorCategory.ReferenceTypeEnumerator;
                    GetEnumeratorMethod = iEnumerableType.GetMethod(
                        name: "GetEnumerator",
                        types: new Type[] { }
                        );
                    EnumeratorType   = iEnumeratorType;
                    GetCurrentMethod = iEnumeratorType.GetProperty("Current").GetMethod;
                }
            }