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); }
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; } }