bool EmitDedicatedMethod(Compiler.CompilerContext ctx, Compiler.Local valueFrom, bool read) { System.Reflection.Emit.MethodBuilder method = ctx.GetDedicatedMethod(key, read); if (method == null) return false; using (Compiler.Local token = new ProtoBuf.Compiler.Local(ctx, typeof(SubItemToken))) { Type rwType = read ? typeof(ProtoReader) : typeof(ProtoWriter); ctx.LoadValue(valueFrom); if (!read) // write requires the object for StartSubItem; read doesn't { if (type.IsValueType) { ctx.LoadNullRef(); } else { ctx.CopyValue(); } } ctx.LoadReaderWriter(); ctx.EmitCall(rwType.GetMethod("StartSubItem")); ctx.StoreValue(token); // note: value already on the stack ctx.LoadReaderWriter(); ctx.EmitCall(method); // handle inheritance (we will be calling the *base* version of things, // but we expect Read to return the "type" type) if (read && type != method.ReturnType) ctx.Cast(this.type); ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(rwType.GetMethod("EndSubItem")); } return true; }
bool EmitDedicatedMethod(Compiler.CompilerContext ctx, Compiler.Local valueFrom, bool read) { #if SILVERLIGHT return false; #else MethodBuilder method = ctx.GetDedicatedMethod(key, read); if (method == null) return false; using (Compiler.Local token = new ProtoBuf.Compiler.Local(ctx, ctx.MapType(typeof(SubItemToken)))) { Type rwType = ctx.MapType(read ? typeof(ProtoReader) : typeof(ProtoWriter)); ctx.LoadValue(valueFrom); if (!read) // write requires the object for StartSubItem; read doesn't { // (if recursion-check is disabled [subtypes] then null is fine too) if (type.IsValueType || !recursionCheck) { ctx.LoadNullRef(); } else { ctx.CopyValue(); } } ctx.LoadReaderWriter(); ctx.EmitCall(rwType.GetMethod("StartSubItem")); ctx.StoreValue(token); // note: value already on the stack ctx.LoadReaderWriter(); ctx.EmitCall(method); // handle inheritance (we will be calling the *base* version of things, // but we expect Read to return the "type" type) if (read && type != method.ReturnType) ctx.Cast(this.type); ctx.LoadValue(token); ctx.LoadReaderWriter(); ctx.EmitCall(rwType.GetMethod("EndSubItem")); } return true; #endif }