static Action <MemberInfo, TextWriter, object, int> GetSemiStaticSerializerFor(Type type, Options opts) { var key = Tuple.Create(type, opts); var ret = (Action <MemberInfo, TextWriter, object, int>)GetSemiStaticSerializerForCache[key]; if (ret != null) { return(ret); } var getSemiStaticSerializer = GetSemiStaticInlineSerializerFor.MakeGenericMethod(type); var invoke = typeof(Action <, ,>).MakeGenericType(typeof(TextWriter), type, typeof(int)).GetMethod("Invoke"); var emit = Emit.NewDynamicMethod(typeof(void), new[] { typeof(MemberInfo), typeof(TextWriter), typeof(object), typeof(int) }, doVerify: Utils.DoVerify); var optsField = OptionsLookup.GetOptionsFieldFor(opts); emit.LoadArgument(0); // MemberInfo emit.LoadField(optsField); // MemberInfo Options emit.Call(getSemiStaticSerializer); // Action<TextWriter, Type, int> emit.LoadArgument(1); // Action<TextWriter, Type, int> TextWriter emit.LoadArgument(2); // Action<TextWriter, Type, int> TextWriter object if (type.IsValueType) { emit.UnboxAny(type); // Action<TextWriter, Type, int> TextWriter type } else { emit.CastClass(type); // Action<TextWriter, Type, int> TextWriter type } emit.LoadArgument(3); // Action<TextWriter, Type, int> TextWriter type int emit.Call(invoke); // --empty-- emit.Return(); // --empty-- lock (GetSemiStaticSerializerForCache) { ret = (Action <MemberInfo, TextWriter, object, int>)GetSemiStaticSerializerForCache[key]; if (ret != null) { return(ret); } GetSemiStaticSerializerForCache[key] = ret = emit.CreateDelegate <Action <MemberInfo, TextWriter, object, int> >(optimizationOptions: Utils.DelegateOptimizationOptions); } return(ret); }
static Action <TextWriter, T, int> _GetFor( bool prettyPrint, bool excludeNulls, bool jsonp, DateTimeFormat dateFormat, bool includeInherited ) { var opts = new Options(prettyPrint, excludeNulls, jsonp, dateFormat, includeInherited); var cached = (Action <TextWriter, T, int>)Cache[opts]; if (cached != null) { return(cached); } lock (Cache) { cached = (Action <TextWriter, T, int>)Cache[opts]; if (cached != null) { return(cached); } var type = typeof(T); var optionsField = OptionsLookup.GetOptionsFieldFor(opts); var serializeMtd = DynamicSerializer.SerializeMtd; var emit = Emit.NewDynamicMethod(typeof(void), new[] { typeof(TextWriter), type, typeof(int) }, doVerify: Utils.DoVerify); emit.LoadArgument(0); // TextWriter emit.LoadArgument(1); // TextWriter T emit.LoadField(optionsField); // TextWriter T options emit.LoadArgument(2); // TextWriter T options int emit.Call(serializeMtd); // --empty-- emit.Return(); Cache[opts] = cached = emit.CreateDelegate <Action <TextWriter, T, int> >(Utils.DelegateOptimizationOptions); return(cached); } }