private void EmitBeq(CompilerContext ctx, CodeLabel label, Type type) { switch (Helpers.GetTypeCode(type)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.Char: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: case ProtoTypeCode.Single: case ProtoTypeCode.Double: ctx.BranchIfEqual(label, false); return; } MethodInfo method = type.GetMethod("op_Equality", BindingFlags.Public | BindingFlags.Static, null, new Type[] { type, type }, null); if ((method == null) || (method.ReturnType != ctx.MapType(typeof(bool)))) { throw new InvalidOperationException("No suitable equality operator found for default-values of type: " + type.FullName); } ctx.EmitCall(method); ctx.BranchIfTrue(label, false); }
protected override void EmitWrite(CompilerContext ctx, Local valueFrom) { using (Local local = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { MethodInfo info; MethodInfo info2; MethodInfo method = this.GetEnumeratorInfo(ctx.Model, out info, out info2); Type returnType = method.ReturnType; bool writePacked = this.WritePacked; using (Local local2 = new Local(ctx, returnType)) { using (Local local3 = writePacked ? new Local(ctx, ctx.MapType(typeof(SubItemToken))) : null) { if (writePacked) { ctx.LoadValue(this.fieldNumber); ctx.LoadValue(2); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); ctx.LoadValue(local); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); ctx.StoreValue(local3); ctx.LoadValue(this.fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField")); } ctx.LoadAddress(local, this.ExpectedType); ctx.EmitCall(method); ctx.StoreValue(local2); using (ctx.Using(local2)) { CodeLabel label = ctx.DefineLabel(); CodeLabel label2 = ctx.DefineLabel(); ctx.Branch(label2, false); ctx.MarkLabel(label); ctx.LoadAddress(local2, returnType); ctx.EmitCall(info2); Type expectedType = base.Tail.ExpectedType; if ((expectedType != ctx.MapType(typeof(object))) && (info2.ReturnType == ctx.MapType(typeof(object)))) { ctx.CastFromObject(expectedType); } base.Tail.EmitWrite(ctx, null); ctx.MarkLabel(label2); ctx.LoadAddress(local2, returnType); ctx.EmitCall(info); ctx.BranchIfTrue(label, false); } if (writePacked) { ctx.LoadValue(local3); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); } } } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { bool returnList = this.ReturnList; bool castListForAdd = !this.add.DeclaringType.IsAssignableFrom(this.declaredType); using (Local local = this.AppendToCollection ? ctx.GetLocalWithValue(this.ExpectedType, valueFrom) : new Local(ctx, this.declaredType)) { using (Local local2 = (returnList && this.AppendToCollection) ? new Local(ctx, this.ExpectedType) : null) { if (!this.AppendToCollection) { ctx.LoadNullRef(); ctx.StoreValue(local); } else if (returnList) { ctx.LoadValue(local); ctx.StoreValue(local2); } if (this.concreteType != null) { ctx.LoadValue(local); CodeLabel label = ctx.DefineLabel(); ctx.BranchIfTrue(label, true); ctx.EmitCtor(this.concreteType); ctx.StoreValue(local); ctx.MarkLabel(label); } EmitReadList(ctx, local, base.Tail, this.add, this.packedWireType, castListForAdd); if (returnList) { if (this.AppendToCollection) { ctx.LoadValue(local2); ctx.LoadValue(local); CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); ctx.BranchIfEqual(label2, true); ctx.LoadValue(local); ctx.Branch(label3, true); ctx.MarkLabel(label2); ctx.LoadNullRef(); ctx.MarkLabel(label3); } else { ctx.LoadValue(local); } } } } }
void IProtoTypeSerializer.EmitCallback(CompilerContext ctx, Local valueFrom, TypeModel.CallbackType callbackType) { bool copyValue = false; if (this.CanHaveInheritance) { for (int i = 0; i < this.serializers.Length; i++) { IProtoSerializer serializer = this.serializers[i]; if ((serializer.ExpectedType != this.forType) && ((IProtoTypeSerializer)serializer).HasCallbacks(callbackType)) { copyValue = true; } } } MethodInfo method = (this.callbacks == null) ? null : this.callbacks[callbackType]; if ((method != null) || copyValue) { ctx.LoadAddress(valueFrom, this.ExpectedType); EmitInvokeCallback(ctx, method, copyValue, null, this.forType); if (copyValue) { CodeLabel label = ctx.DefineLabel(); for (int j = 0; j < this.serializers.Length; j++) { IProtoTypeSerializer serializer3; IProtoSerializer serializer2 = this.serializers[j]; Type expectedType = serializer2.ExpectedType; if ((expectedType != this.forType) && (serializer3 = (IProtoTypeSerializer)serializer2).HasCallbacks(callbackType)) { CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); ctx.CopyValue(); ctx.TryCast(expectedType); ctx.CopyValue(); ctx.BranchIfTrue(label2, true); ctx.DiscardValue(); ctx.Branch(label3, false); ctx.MarkLabel(label2); serializer3.EmitCallback(ctx, null, callbackType); ctx.Branch(label, false); ctx.MarkLabel(label3); } } ctx.MarkLabel(label); ctx.DiscardValue(); } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { base.Tail.EmitRead(ctx, valueFrom); ctx.CopyValue(); CodeLabel label = ctx.DefineLabel(); CodeLabel label2 = ctx.DefineLabel(); ctx.LoadValue(typeof(string).GetProperty("Length")); ctx.BranchIfTrue(label, true); ctx.DiscardValue(); ctx.LoadNullRef(); ctx.Branch(label2, true); ctx.MarkLabel(label); ctx.EmitCtor(ctx.MapType(typeof(Uri)), new Type[] { ctx.MapType(typeof(string)) }); ctx.MarkLabel(label2); }
private void EmitCreateIfNull(CompilerContext ctx, Local storage) { if (!this.ExpectedType.IsValueType) { CodeLabel label = ctx.DefineLabel(); ctx.LoadValue(storage); ctx.BranchIfTrue(label, false); ((IProtoTypeSerializer)this).EmitCreateInstance(ctx); if (this.callbacks != null) { EmitInvokeCallback(ctx, this.callbacks.BeforeDeserialize, true, null, this.forType); } ctx.StoreValue(storage); ctx.MarkLabel(label); } }
internal static void EmitReadList(CompilerContext ctx, Local list, IProtoSerializer tail, MethodInfo add, WireType packedWireType, bool castListForAdd) { using (Local local = new Local(ctx, ctx.MapType(typeof(int)))) { CodeLabel codeLabel = (packedWireType == WireType.None ? new CodeLabel() : ctx.DefineLabel()); if (packedWireType != WireType.None) { ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("WireType")); ctx.LoadValue(2); ctx.BranchIfEqual(codeLabel, false); } ctx.LoadReaderWriter(); ctx.LoadValue(typeof(ProtoReader).GetProperty("FieldNumber")); ctx.StoreValue(local); CodeLabel codeLabel1 = ctx.DefineLabel(); ctx.MarkLabel(codeLabel1); ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.LoadReaderWriter(); ctx.LoadValue(local); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("TryReadFieldHeader")); ctx.BranchIfTrue(codeLabel1, false); if (packedWireType != WireType.None) { CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.Branch(codeLabel2, false); ctx.MarkLabel(codeLabel); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("StartSubItem")); CodeLabel codeLabel3 = ctx.DefineLabel(); CodeLabel codeLabel4 = ctx.DefineLabel(); ctx.MarkLabel(codeLabel3); ctx.LoadValue((int)packedWireType); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("HasSubValue")); ctx.BranchIfFalse(codeLabel4, false); ListDecorator.EmitReadAndAddItem(ctx, list, tail, add, castListForAdd); ctx.Branch(codeLabel3, false); ctx.MarkLabel(codeLabel4); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("EndSubItem")); ctx.MarkLabel(codeLabel2); } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { this.Tail.EmitRead(ctx, valueFrom); ctx.CopyValue(); CodeLabel codeLabel = ctx.DefineLabel(); CodeLabel codeLabel1 = ctx.DefineLabel(); ctx.LoadValue(typeof(string).GetProperty("Length")); ctx.BranchIfTrue(codeLabel, true); ctx.DiscardValue(); ctx.LoadNullRef(); ctx.Branch(codeLabel1, true); ctx.MarkLabel(codeLabel); Type type = ctx.MapType(typeof(Uri)); Type[] typeArray = new Type[] { ctx.MapType(typeof(string)) }; ctx.EmitCtor(type, typeArray); ctx.MarkLabel(codeLabel1); }
private void WriteFieldHandler(CompilerContext ctx, Type expected, Local loc, CodeLabel handler, CodeLabel @continue, IProtoSerializer serializer) { ctx.MarkLabel(handler); Type expectedType = serializer.ExpectedType; if (expectedType == this.forType) { this.EmitCreateIfNull(ctx, loc); serializer.EmitRead(ctx, loc); } else { RuntimeTypeModel model = (RuntimeTypeModel)ctx.Model; if (((IProtoTypeSerializer)serializer).CanCreateInstance()) { CodeLabel label = ctx.DefineLabel(); ctx.LoadValue(loc); ctx.BranchIfFalse(label, false); ctx.LoadValue(loc); ctx.TryCast(expectedType); ctx.BranchIfTrue(label, false); ctx.LoadReaderWriter(); ctx.LoadValue(loc); ((IProtoTypeSerializer)serializer).EmitCreateInstance(ctx); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("Merge")); ctx.Cast(expected); ctx.StoreValue(loc); ctx.MarkLabel(label); } ctx.LoadValue(loc); ctx.Cast(expectedType); serializer.EmitRead(ctx, null); } if (serializer.ReturnsValue) { ctx.StoreValue(loc); } ctx.Branch(@continue, false); }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { using (Local local = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { ctx.LoadAddress(local, this.ExpectedType); if (base.Tail.RequiresOldValue) { ctx.CopyValue(); ctx.LoadValue(this.field); } ctx.ReadNullCheckedTail(this.field.FieldType, base.Tail, null); if (base.Tail.ReturnsValue) { if (this.field.FieldType.IsValueType) { ctx.StoreValue(this.field); } else { CodeLabel label = ctx.DefineLabel(); CodeLabel label2 = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(label, true); ctx.DiscardValue(); ctx.DiscardValue(); ctx.Branch(label2, true); ctx.MarkLabel(label); ctx.StoreValue(this.field); ctx.MarkLabel(label2); } } else { ctx.DiscardValue(); } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { using (Compiler.Local list = AppendToCollection ? ctx.GetLocalWithValue(ExpectedType, valueFrom) : new Compiler.Local(ctx, typeof(TDictionary))) using (Compiler.Local token = new Compiler.Local(ctx, typeof(SubItemToken))) using (Compiler.Local key = new Compiler.Local(ctx, typeof(TKey))) using (Compiler.Local @value = new Compiler.Local(ctx, typeof(TValue))) using (Compiler.Local fieldNumber = new Compiler.Local(ctx, typeof(int))) { if (!AppendToCollection) { // always new ctx.LoadNullRef(); ctx.StoreValue(list); } if (concreteType != null) { ctx.LoadValue(list); Compiler.CodeLabel notNull = ctx.DefineLabel(); ctx.BranchIfTrue(notNull, true); ctx.EmitCtor(concreteType); ctx.StoreValue(list); ctx.MarkLabel(notNull); } var redoFromStart = ctx.DefineLabel(); ctx.MarkLabel(redoFromStart); // key = default(TKey); value = default(TValue); if (typeof(TKey) == typeof(string)) { ctx.LoadValue(""); ctx.StoreValue(key); } else { ctx.InitLocal(typeof(TKey), key); } if (typeof(TValue) == typeof(string)) { ctx.LoadValue(""); ctx.StoreValue(value); } else { ctx.InitLocal(typeof(TValue), @value); } // token = ProtoReader.StartSubItem(reader); ctx.LoadReader(true); ctx.EmitCall(typeof(ProtoReader).GetMethod("StartSubItem", ProtoReader.State.ReaderStateTypeArray)); ctx.StoreValue(token); Compiler.CodeLabel @continue = ctx.DefineLabel(), processField = ctx.DefineLabel(); // while ... ctx.Branch(@continue, false); // switch(fieldNumber) ctx.MarkLabel(processField); ctx.LoadValue(fieldNumber); CodeLabel @default = ctx.DefineLabel(), one = ctx.DefineLabel(), two = ctx.DefineLabel(); ctx.Switch(new[] { @default, one, two }); // zero based, hence explicit 0 // case 0: default: reader.SkipField(); ctx.MarkLabel(@default); ctx.LoadReader(true); ctx.EmitCall(typeof(ProtoReader).GetMethod("SkipField", ProtoReader.State.StateTypeArray)); ctx.Branch(@continue, false); // case 1: key = ... ctx.MarkLabel(one); keyTail.EmitRead(ctx, null); ctx.StoreValue(key); ctx.Branch(@continue, false); // case 2: value = ... ctx.MarkLabel(two); Tail.EmitRead(ctx, Tail.RequiresOldValue ? @value : null); ctx.StoreValue(value); // (fieldNumber = reader.ReadFieldHeader()) > 0 ctx.MarkLabel(@continue); ctx.EmitBasicRead("ReadFieldHeader", typeof(int)); ctx.CopyValue(); ctx.StoreValue(fieldNumber); ctx.LoadValue(0); ctx.BranchIfGreater(processField, false); // ProtoReader.EndSubItem(token, reader); ctx.LoadValue(token); ctx.LoadReader(true); ctx.EmitCall(typeof(ProtoReader).GetMethod("EndSubItem", new[] { typeof(SubItemToken), typeof(ProtoReader), ProtoReader.State.ByRefStateType })); // list[key] = value; ctx.LoadAddress(list, ExpectedType); ctx.LoadValue(key); ctx.LoadValue(@value); ctx.EmitCall(indexerSet); // while reader.TryReadFieldReader(fieldNumber) ctx.LoadReader(true); ctx.LoadValue(this.fieldNumber); ctx.EmitCall(typeof(ProtoReader).GetMethod("TryReadFieldHeader", new[] { ProtoReader.State.ByRefStateType, typeof(int) })); ctx.BranchIfTrue(redoFromStart, false); if (ReturnsValue) { ctx.LoadValue(list); } } }
protected override void EmitWrite(CompilerContext ctx, Local valueFrom) { MethodInfo methodInfo; MethodInfo methodInfo1; Local local; using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { MethodInfo enumeratorInfo = this.GetEnumeratorInfo(ctx.Model, out methodInfo, out methodInfo1); Type returnType = enumeratorInfo.ReturnType; bool writePacked = this.WritePacked; using (Local local1 = new Local(ctx, returnType)) { if (writePacked) { local = new Local(ctx, ctx.MapType(typeof(SubItemToken))); } else { local = null; } using (Local local2 = local) { if (writePacked) { ctx.LoadValue(this.fieldNumber); ctx.LoadValue(2); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("WriteFieldHeader")); ctx.LoadValue(localWithValue); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("StartSubItem")); ctx.StoreValue(local2); ctx.LoadValue(this.fieldNumber); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("SetPackedField")); } ctx.LoadAddress(localWithValue, this.ExpectedType); ctx.EmitCall(enumeratorInfo); ctx.StoreValue(local1); using (IDisposable disposable = ctx.Using(local1)) { CodeLabel codeLabel = ctx.DefineLabel(); CodeLabel codeLabel1 = ctx.DefineLabel(); ctx.Branch(codeLabel1, false); ctx.MarkLabel(codeLabel); ctx.LoadAddress(local1, returnType); ctx.EmitCall(methodInfo1); Type expectedType = this.Tail.ExpectedType; if (expectedType != ctx.MapType(typeof(object)) && methodInfo1.ReturnType == ctx.MapType(typeof(object))) { ctx.CastFromObject(expectedType); } this.Tail.EmitWrite(ctx, null); ctx.MarkLabel(codeLabel1); ctx.LoadAddress(local1, returnType); ctx.EmitCall(methodInfo); ctx.BranchIfTrue(codeLabel, false); } if (writePacked) { ctx.LoadValue(local2); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("EndSubItem")); } } } } }
protected override void EmitWrite(CompilerContext ctx, Local valueFrom) { Type itemType = typeof(KeyValuePair <TKey, TValue>); MethodInfo moveNext, current, getEnumerator = ListDecorator.GetEnumeratorInfo( ExpectedType, itemType, out moveNext, out current); Type enumeratorType = getEnumerator.ReturnType; MethodInfo key = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Key)).GetGetMethod(), @value = itemType.GetProperty(nameof(KeyValuePair <TKey, TValue> .Value)).GetGetMethod(); using (Compiler.Local list = ctx.GetLocalWithValue(ExpectedType, valueFrom)) using (Compiler.Local iter = new Compiler.Local(ctx, enumeratorType)) using (Compiler.Local token = new Compiler.Local(ctx, typeof(SubItemToken))) using (Compiler.Local kvp = new Compiler.Local(ctx, itemType)) { ctx.LoadAddress(list, ExpectedType); ctx.EmitCall(getEnumerator, ExpectedType); ctx.StoreValue(iter); using (ctx.Using(iter)) { Compiler.CodeLabel body = ctx.DefineLabel(), next = ctx.DefineLabel(); ctx.Branch(next, false); ctx.MarkLabel(body); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(current, enumeratorType); if (itemType != typeof(object) && current.ReturnType == typeof(object)) { ctx.CastFromObject(itemType); } ctx.StoreValue(kvp); ctx.LoadValue(fieldNumber); ctx.LoadValue((int)wireType); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("WriteFieldHeader")); ctx.LoadNullRef(); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("StartSubItem")); ctx.StoreValue(token); ctx.LoadAddress(kvp, itemType); ctx.EmitCall(key, itemType); ctx.WriteNullCheckedTail(typeof(TKey), keyTail, null); ctx.LoadAddress(kvp, itemType); ctx.EmitCall(value, itemType); ctx.WriteNullCheckedTail(typeof(TValue), Tail, null); ctx.LoadValue(token); ctx.LoadWriter(true); ctx.EmitCall(ProtoWriter.GetStaticMethod("EndSubItem")); ctx.MarkLabel(@next); ctx.LoadAddress(iter, enumeratorType); ctx.EmitCall(moveNext, enumeratorType); ctx.BranchIfTrue(body, false); } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { Local local; bool returnList = this.ReturnList; using (Local local1 = (this.AppendToCollection ? ctx.GetLocalWithValue(this.ExpectedType, valueFrom) : new Local(ctx, this.declaredType))) { if (!returnList || !this.AppendToCollection) { local = null; } else { local = new Local(ctx, this.ExpectedType); } using (Local local2 = local) { if (!this.AppendToCollection) { ctx.LoadNullRef(); ctx.StoreValue(local1); } else if (returnList) { ctx.LoadValue(local1); ctx.StoreValue(local2); } if (this.concreteType != null) { ctx.LoadValue(local1); CodeLabel codeLabel = ctx.DefineLabel(); ctx.BranchIfTrue(codeLabel, true); ctx.EmitCtor(this.concreteType); ctx.StoreValue(local1); ctx.MarkLabel(codeLabel); } bool flag = [email protected](this.declaredType); ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, flag); if (returnList) { if (!this.AppendToCollection) { ctx.LoadValue(local1); } else { ctx.LoadValue(local2); ctx.LoadValue(local1); CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.BranchIfEqual(codeLabel1, true); ctx.LoadValue(local1); ctx.Branch(codeLabel2, true); ctx.MarkLabel(codeLabel1); ctx.LoadNullRef(); ctx.MarkLabel(codeLabel2); } } } } }
protected override void EmitRead(CompilerContext ctx, Local valueFrom) { MethodInfo methodInfo; MethodInfo methodInfo1; Local localWithValue; if (base.AppendToCollection) { localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom); } else { localWithValue = null; } using (Local local = localWithValue) { using (Local local1 = new Local(ctx, this.builderFactory.ReturnType)) { ctx.EmitCall(this.builderFactory); ctx.StoreValue(local1); if (base.AppendToCollection) { CodeLabel codeLabel = ctx.DefineLabel(); if (!this.ExpectedType.IsValueType) { ctx.LoadValue(local); ctx.BranchIfFalse(codeLabel, false); } PropertyInfo property = Helpers.GetProperty(this.ExpectedType, "Length", false) ?? Helpers.GetProperty(this.ExpectedType, "Count", false) ?? Helpers.GetProperty(ImmutableCollectionDecorator.ResolveIReadOnlyCollection(this.ExpectedType, this.Tail.ExpectedType), "Count", false); ctx.LoadAddress(local, local.Type); ctx.EmitCall(Helpers.GetGetMethod(property, false, false)); ctx.BranchIfFalse(codeLabel, false); Type type = ctx.MapType(typeof(void)); if (this.addRange == null) { MethodInfo enumeratorInfo = base.GetEnumeratorInfo(ctx.Model, out methodInfo, out methodInfo1); Type returnType = enumeratorInfo.ReturnType; using (Local local2 = new Local(ctx, returnType)) { ctx.LoadAddress(local, this.ExpectedType); ctx.EmitCall(enumeratorInfo); ctx.StoreValue(local2); using (IDisposable disposable = ctx.Using(local2)) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.Branch(codeLabel2, false); ctx.MarkLabel(codeLabel1); ctx.LoadAddress(local1, local1.Type); ctx.LoadAddress(local2, returnType); ctx.EmitCall(methodInfo1); ctx.EmitCall(this.@add); if ([email protected] != null && [email protected] != type) { ctx.DiscardValue(); } ctx.MarkLabel(codeLabel2); ctx.LoadAddress(local2, returnType); ctx.EmitCall(methodInfo); ctx.BranchIfTrue(codeLabel1, false); } } } else { ctx.LoadValue(local1); ctx.LoadValue(local); ctx.EmitCall(this.addRange); if (this.addRange.ReturnType != null && [email protected] != type) { ctx.DiscardValue(); } } ctx.MarkLabel(codeLabel); } ListDecorator.EmitReadList(ctx, local1, this.Tail, this.@add, this.packedWireType, false); ctx.LoadAddress(local1, local1.Type); ctx.EmitCall(this.finish); if (this.ExpectedType != this.finish.ReturnType) { ctx.Cast(this.ExpectedType); } } } }
public void EmitRead(CompilerContext ctx, Local incoming) { using (Local local = ctx.GetLocalWithValue(this.ExpectedType, incoming)) { Local[] localArray = new Local[this.members.Length]; try { for (int i = 0; i < localArray.Length; i++) { Type memberType = this.GetMemberType(i); bool flag = true; localArray[i] = new Local(ctx, memberType); if (this.ExpectedType.IsValueType) { continue; } if (memberType.IsValueType) { switch (Helpers.GetTypeCode(memberType)) { case ProtoTypeCode.Boolean: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: ctx.LoadValue(0); goto Label_0108; case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: ctx.LoadValue((long)0L); goto Label_0108; case ProtoTypeCode.Single: ctx.LoadValue((float)0f); goto Label_0108; case ProtoTypeCode.Double: ctx.LoadValue((double)0.0); goto Label_0108; case ProtoTypeCode.Decimal: ctx.LoadValue((decimal)0M); goto Label_0108; case ProtoTypeCode.Guid: ctx.LoadValue(Guid.Empty); goto Label_0108; } ctx.LoadAddress(localArray[i], memberType); ctx.EmitCtor(memberType); flag = false; } else { ctx.LoadNullRef(); } Label_0108: if (flag) { ctx.StoreValue(localArray[i]); } } CodeLabel label = this.ExpectedType.IsValueType ? new CodeLabel() : ctx.DefineLabel(); if (!this.ExpectedType.IsValueType) { ctx.LoadAddress(local, this.ExpectedType); ctx.BranchIfFalse(label, false); } for (int j = 0; j < this.members.Length; j++) { ctx.LoadAddress(local, this.ExpectedType); switch (this.members[j].MemberType) { case MemberTypes.Field: ctx.LoadValue((FieldInfo)this.members[j]); break; case MemberTypes.Property: ctx.LoadValue((PropertyInfo)this.members[j]); break; } ctx.StoreValue(localArray[j]); } if (!this.ExpectedType.IsValueType) { ctx.MarkLabel(label); } using (Local local2 = new Local(ctx, ctx.MapType(typeof(int)))) { CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); CodeLabel label4 = ctx.DefineLabel(); ctx.Branch(label2, false); CodeLabel[] jumpTable = new CodeLabel[this.members.Length]; for (int m = 0; m < this.members.Length; m++) { jumpTable[m] = ctx.DefineLabel(); } ctx.MarkLabel(label3); ctx.LoadValue(local2); ctx.LoadValue(1); ctx.Subtract(); ctx.Switch(jumpTable); ctx.Branch(label4, false); for (int n = 0; n < jumpTable.Length; n++) { ctx.MarkLabel(jumpTable[n]); IProtoSerializer tail = this.tails[n]; Local valueFrom = tail.RequiresOldValue ? localArray[n] : null; ctx.ReadNullCheckedTail(localArray[n].Type, tail, valueFrom); if (tail.ReturnsValue) { if (localArray[n].Type.IsValueType) { ctx.StoreValue(localArray[n]); } else { CodeLabel label5 = ctx.DefineLabel(); CodeLabel label6 = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(label5, true); ctx.DiscardValue(); ctx.Branch(label6, true); ctx.MarkLabel(label5); ctx.StoreValue(localArray[n]); ctx.MarkLabel(label6); } } ctx.Branch(label2, false); } ctx.MarkLabel(label4); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); ctx.MarkLabel(label2); ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); ctx.CopyValue(); ctx.StoreValue(local2); ctx.LoadValue(0); ctx.BranchIfGreater(label3, false); } for (int k = 0; k < localArray.Length; k++) { ctx.LoadValue(localArray[k]); } ctx.EmitCtor(this.ctor); ctx.StoreValue(local); } finally { for (int num6 = 0; num6 < localArray.Length; num6++) { if (localArray[num6] != null) { localArray[num6].Dispose(); } } } } }
void ProtoBuf.Serializers.IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom) { using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, valueFrom)) { this.EmitCallbackIfNeeded(ctx, localWithValue, TypeModel.CallbackType.BeforeSerialize); CodeLabel codeLabel = ctx.DefineLabel(); if (this.CanHaveInheritance) { for (int i = 0; i < (int)this.serializers.Length; i++) { IProtoSerializer protoSerializer = this.serializers[i]; Type expectedType = protoSerializer.ExpectedType; if (expectedType != this.forType) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.LoadValue(localWithValue); ctx.TryCast(expectedType); ctx.CopyValue(); ctx.BranchIfTrue(codeLabel1, true); ctx.DiscardValue(); ctx.Branch(codeLabel2, true); ctx.MarkLabel(codeLabel1); protoSerializer.EmitWrite(ctx, null); ctx.Branch(codeLabel, false); ctx.MarkLabel(codeLabel2); } } if (this.constructType == null || this.constructType == this.forType) { ctx.LoadValue(localWithValue); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.LoadValue(this.forType); ctx.BranchIfEqual(codeLabel, true); } else { using (Local local = new Local(ctx, ctx.MapType(typeof(Type)))) { ctx.LoadValue(localWithValue); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.CopyValue(); ctx.StoreValue(local); ctx.LoadValue(this.forType); ctx.BranchIfEqual(codeLabel, true); ctx.LoadValue(local); ctx.LoadValue(this.constructType); ctx.BranchIfEqual(codeLabel, true); } } ctx.LoadValue(this.forType); ctx.LoadValue(localWithValue); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)); } ctx.MarkLabel(codeLabel); for (int j = 0; j < (int)this.serializers.Length; j++) { IProtoSerializer protoSerializer1 = this.serializers[j]; if (protoSerializer1.ExpectedType == this.forType) { protoSerializer1.EmitWrite(ctx, localWithValue); } } if (this.isExtensible) { ctx.LoadValue(localWithValue); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData")); } this.EmitCallbackIfNeeded(ctx, localWithValue, TypeModel.CallbackType.AfterSerialize); } }
void ProtoBuf.Serializers.IProtoTypeSerializer.EmitCallback(CompilerContext ctx, Local valueFrom, TypeModel.CallbackType callbackType) { MethodInfo item; bool flag = false; if (this.CanHaveInheritance) { for (int i = 0; i < (int)this.serializers.Length; i++) { IProtoSerializer protoSerializer = this.serializers[i]; if (protoSerializer.ExpectedType != this.forType && ((IProtoTypeSerializer)protoSerializer).HasCallbacks(callbackType)) { flag = true; } } } if (this.callbacks == null) { item = null; } else { item = this.callbacks[callbackType]; } MethodInfo methodInfo = item; if (methodInfo == null && !flag) { return; } ctx.LoadAddress(valueFrom, this.ExpectedType); TypeSerializer.EmitInvokeCallback(ctx, methodInfo, flag, null, this.forType); if (flag) { CodeLabel codeLabel = ctx.DefineLabel(); for (int j = 0; j < (int)this.serializers.Length; j++) { IProtoSerializer protoSerializer1 = this.serializers[j]; Type expectedType = protoSerializer1.ExpectedType; if (expectedType != this.forType) { IProtoTypeSerializer protoTypeSerializer = (IProtoTypeSerializer)protoSerializer1; IProtoTypeSerializer protoTypeSerializer1 = protoTypeSerializer; if (protoTypeSerializer.HasCallbacks(callbackType)) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); ctx.CopyValue(); ctx.TryCast(expectedType); ctx.CopyValue(); ctx.BranchIfTrue(codeLabel1, true); ctx.DiscardValue(); ctx.Branch(codeLabel2, false); ctx.MarkLabel(codeLabel1); protoTypeSerializer1.EmitCallback(ctx, null, callbackType); ctx.Branch(codeLabel, false); ctx.MarkLabel(codeLabel2); } } } ctx.MarkLabel(codeLabel); ctx.DiscardValue(); } }
public void EmitRead(CompilerContext ctx, Local incoming) { Local local; using (Local localWithValue = ctx.GetLocalWithValue(this.ExpectedType, incoming)) { Local[] localArray = new Local[(int)this.members.Length]; try { for (int i = 0; i < (int)localArray.Length; i++) { Type memberType = this.GetMemberType(i); bool flag = true; localArray[i] = new Local(ctx, memberType); if (!this.ExpectedType.IsValueType) { if (!memberType.IsValueType) { ctx.LoadNullRef(); } else { ProtoTypeCode typeCode = Helpers.GetTypeCode(memberType); switch (typeCode) { case ProtoTypeCode.Boolean: case ProtoTypeCode.SByte: case ProtoTypeCode.Byte: case ProtoTypeCode.Int16: case ProtoTypeCode.UInt16: case ProtoTypeCode.Int32: case ProtoTypeCode.UInt32: { ctx.LoadValue(0); break; } case ProtoTypeCode.Char: { ctx.LoadAddress(localArray[i], memberType); ctx.EmitCtor(memberType); flag = false; break; } case ProtoTypeCode.Int64: case ProtoTypeCode.UInt64: { ctx.LoadValue((long)0); break; } case ProtoTypeCode.Single: { ctx.LoadValue(0f); break; } case ProtoTypeCode.Double: { ctx.LoadValue(0); break; } case ProtoTypeCode.Decimal: { ctx.LoadValue(new decimal(0)); break; } default: { if (typeCode == ProtoTypeCode.Guid) { ctx.LoadValue(Guid.Empty); break; } else { goto case ProtoTypeCode.Char; } } } } if (flag) { ctx.StoreValue(localArray[i]); } } } CodeLabel codeLabel = (this.ExpectedType.IsValueType ? new CodeLabel() : ctx.DefineLabel()); if (!this.ExpectedType.IsValueType) { ctx.LoadAddress(localWithValue, this.ExpectedType); ctx.BranchIfFalse(codeLabel, false); } for (int j = 0; j < (int)this.members.Length; j++) { ctx.LoadAddress(localWithValue, this.ExpectedType); MemberTypes memberType1 = this.members[j].MemberType; if (memberType1 == MemberTypes.Field) { ctx.LoadValue((FieldInfo)this.members[j]); } else if (memberType1 == MemberTypes.Property) { ctx.LoadValue((PropertyInfo)this.members[j]); } ctx.StoreValue(localArray[j]); } if (!this.ExpectedType.IsValueType) { ctx.MarkLabel(codeLabel); } using (Local local1 = new Local(ctx, ctx.MapType(typeof(int)))) { CodeLabel codeLabel1 = ctx.DefineLabel(); CodeLabel codeLabel2 = ctx.DefineLabel(); CodeLabel codeLabel3 = ctx.DefineLabel(); ctx.Branch(codeLabel1, false); CodeLabel[] codeLabelArray = new CodeLabel[(int)this.members.Length]; for (int k = 0; k < (int)this.members.Length; k++) { codeLabelArray[k] = ctx.DefineLabel(); } ctx.MarkLabel(codeLabel2); ctx.LoadValue(local1); ctx.LoadValue(1); ctx.Subtract(); ctx.Switch(codeLabelArray); ctx.Branch(codeLabel3, false); for (int l = 0; l < (int)codeLabelArray.Length; l++) { ctx.MarkLabel(codeLabelArray[l]); IProtoSerializer protoSerializer = this.tails[l]; if (protoSerializer.RequiresOldValue) { local = localArray[l]; } else { local = null; } ctx.ReadNullCheckedTail(localArray[l].Type, protoSerializer, local); if (protoSerializer.ReturnsValue) { if (!localArray[l].Type.IsValueType) { CodeLabel codeLabel4 = ctx.DefineLabel(); CodeLabel codeLabel5 = ctx.DefineLabel(); ctx.CopyValue(); ctx.BranchIfTrue(codeLabel4, true); ctx.DiscardValue(); ctx.Branch(codeLabel5, true); ctx.MarkLabel(codeLabel4); ctx.StoreValue(localArray[l]); ctx.MarkLabel(codeLabel5); } else { ctx.StoreValue(localArray[l]); } } ctx.Branch(codeLabel1, false); } ctx.MarkLabel(codeLabel3); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoReader)).GetMethod("SkipField")); ctx.MarkLabel(codeLabel1); ctx.EmitBasicRead("ReadFieldHeader", ctx.MapType(typeof(int))); ctx.CopyValue(); ctx.StoreValue(local1); ctx.LoadValue(0); ctx.BranchIfGreater(codeLabel2, false); } for (int m = 0; m < (int)localArray.Length; m++) { ctx.LoadValue(localArray[m]); } ctx.EmitCtor(this.ctor); ctx.StoreValue(localWithValue); } finally { for (int n = 0; n < (int)localArray.Length; n++) { if (localArray[n] != null) { localArray[n].Dispose(); } } } } }
private void EmitBranchIfDefaultValue(CompilerContext ctx, CodeLabel label) { Type expectedType = this.ExpectedType; ProtoTypeCode typeCode = Helpers.GetTypeCode(expectedType); switch (typeCode) { case ProtoTypeCode.Boolean: { if ((bool)this.defaultValue) { ctx.BranchIfTrue(label, false); return; } ctx.BranchIfFalse(label, false); return; } case ProtoTypeCode.Char: { if ((char)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((char)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.SByte: { if ((sbyte)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((sbyte)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Byte: { if ((byte)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((int)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Int16: { if ((short)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((short)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.UInt16: { if ((ushort)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((int)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Int32: { if ((int)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((int)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.UInt32: { if ((uint)this.defaultValue == 0) { ctx.BranchIfFalse(label, false); return; } ctx.LoadValue((int)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Int64: { ctx.LoadValue((long)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.UInt64: { ctx.LoadValue((long)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Single: { ctx.LoadValue((float)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Double: { ctx.LoadValue((double)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Decimal: { ctx.LoadValue((decimal)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.DateTime: { ctx.LoadValue(((DateTime)this.defaultValue).ToBinary()); ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary")); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.Unknown | ProtoTypeCode.DateTime: { throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName)); } case ProtoTypeCode.String: { ctx.LoadValue((string)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } default: { switch (typeCode) { case ProtoTypeCode.TimeSpan: { TimeSpan timeSpan = (TimeSpan)this.defaultValue; if (timeSpan != TimeSpan.Zero) { ctx.LoadValue(timeSpan.Ticks); ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks")); } else { ctx.LoadValue(typeof(TimeSpan).GetField("Zero")); } this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.ByteArray: { throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName)); } case ProtoTypeCode.Guid: { ctx.LoadValue((Guid)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } default: { throw new NotSupportedException(string.Concat("Type cannot be represented as a default value: ", expectedType.FullName)); } } break; } } }
private void EmitBranchIfDefaultValue(CompilerContext ctx, CodeLabel label) { Type expectedType = this.ExpectedType; switch (Helpers.GetTypeCode(expectedType)) { case ProtoTypeCode.Boolean: if (!((bool)this.defaultValue)) { ctx.BranchIfFalse(label, false); return; } ctx.BranchIfTrue(label, false); return; case ProtoTypeCode.Char: if (((char)this.defaultValue) != '\0') { ctx.LoadValue((int)((char)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.SByte: if (((sbyte)this.defaultValue) != 0) { ctx.LoadValue((int)((sbyte)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.Byte: if (((byte)this.defaultValue) != 0) { ctx.LoadValue((int)((byte)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.Int16: if (((short)this.defaultValue) != 0) { ctx.LoadValue((int)((short)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.UInt16: if (((ushort)this.defaultValue) != 0) { ctx.LoadValue((int)((ushort)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.Int32: if (((int)this.defaultValue) != 0) { ctx.LoadValue((int)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.UInt32: if (((uint)this.defaultValue) != 0) { ctx.LoadValue((int)((uint)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; } ctx.BranchIfFalse(label, false); return; case ProtoTypeCode.Int64: ctx.LoadValue((long)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.UInt64: ctx.LoadValue((long)((ulong)this.defaultValue)); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.Single: ctx.LoadValue((float)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.Double: ctx.LoadValue((double)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.Decimal: { decimal defaultValue = (decimal)this.defaultValue; ctx.LoadValue(defaultValue); this.EmitBeq(ctx, label, expectedType); return; } case ProtoTypeCode.DateTime: ctx.LoadValue(((DateTime)this.defaultValue).ToBinary()); ctx.EmitCall(ctx.MapType(typeof(DateTime)).GetMethod("FromBinary")); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.String: ctx.LoadValue((string)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; case ProtoTypeCode.TimeSpan: { TimeSpan span = (TimeSpan)this.defaultValue; if (!(span == TimeSpan.Zero)) { ctx.LoadValue(span.Ticks); ctx.EmitCall(ctx.MapType(typeof(TimeSpan)).GetMethod("FromTicks")); break; } ctx.LoadValue(typeof(TimeSpan).GetField("Zero")); break; } case ProtoTypeCode.Guid: ctx.LoadValue((Guid)this.defaultValue); this.EmitBeq(ctx, label, expectedType); return; default: throw new NotSupportedException("Type cannot be represented as a default value: " + expectedType.FullName); } this.EmitBeq(ctx, label, expectedType); }
void IProtoSerializer.EmitWrite(CompilerContext ctx, Local valueFrom) { Type expectedType = this.ExpectedType; using (Local local = ctx.GetLocalWithValue(expectedType, valueFrom)) { this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.BeforeSerialize); CodeLabel label = ctx.DefineLabel(); if (!this.CanHaveInheritance) { goto Label_0206; } for (int i = 0; i < this.serializers.Length; i++) { IProtoSerializer serializer = this.serializers[i]; Type type = serializer.ExpectedType; if (type != this.forType) { CodeLabel label2 = ctx.DefineLabel(); CodeLabel label3 = ctx.DefineLabel(); ctx.LoadValue(local); ctx.TryCast(type); ctx.CopyValue(); ctx.BranchIfTrue(label2, true); ctx.DiscardValue(); ctx.Branch(label3, true); ctx.MarkLabel(label2); serializer.EmitWrite(ctx, null); ctx.Branch(label, false); ctx.MarkLabel(label3); } } if ((this.constructType != null) && (this.constructType != this.forType)) { using (Local local2 = new Local(ctx, ctx.MapType(typeof(Type)))) { ctx.LoadValue(local); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.CopyValue(); ctx.StoreValue(local2); ctx.LoadValue(this.forType); ctx.BranchIfEqual(label, true); ctx.LoadValue(local2); ctx.LoadValue(this.constructType); ctx.BranchIfEqual(label, true); goto Label_01B1; } } ctx.LoadValue(local); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.LoadValue(this.forType); ctx.BranchIfEqual(label, true); Label_01B1: ctx.LoadValue(this.forType); ctx.LoadValue(local); ctx.EmitCall(ctx.MapType(typeof(object)).GetMethod("GetType")); ctx.EmitCall(ctx.MapType(typeof(TypeModel)).GetMethod("ThrowUnexpectedSubtype", BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static)); Label_0206: ctx.MarkLabel(label); for (int j = 0; j < this.serializers.Length; j++) { IProtoSerializer serializer2 = this.serializers[j]; if (serializer2.ExpectedType == this.forType) { serializer2.EmitWrite(ctx, local); } } if (this.isExtensible) { ctx.LoadValue(local); ctx.LoadReaderWriter(); ctx.EmitCall(ctx.MapType(typeof(ProtoWriter)).GetMethod("AppendExtensionData")); } this.EmitCallbackIfNeeded(ctx, local, TypeModel.CallbackType.AfterSerialize); } }