public static void EmitFor(TracingILGenerator il, LocalBuilder count, Action <TracingILGenerator, LocalBuilder> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(count != null); Contract.Requires(bodyEmitter != null); LocalBuilder local = il.DeclareLocal(typeof(int), "i"); il.EmitLdc_I4_0(); il.EmitAnyStloc(local); Label target = il.DefineLabel("FOR_COND"); il.EmitBr(target); Label label = il.DefineLabel("BODY"); il.MarkLabel(label); bodyEmitter(il, local); il.EmitAnyLdloc(local); il.EmitLdc_I4_1(); il.EmitAdd(); il.EmitAnyStloc(local); il.MarkLabel(target); il.EmitAnyLdloc(local); il.EmitAnyLdloc(count); il.EmitBlt(label); }
/// <summary> /// Emits 'for' statement on current IL stream. /// </summary> /// <param name="il">IL generator to be emitted to.</param> /// <param name="count">'count' local variable which is <see cref="Int32"/> type and holds maximum loop count.</param> /// <param name="bodyEmitter">Delegate to emit for statement body.</param> public static void EmitFor(TracingILGenerator il, LocalBuilder count, Action <TracingILGenerator, LocalBuilder> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(count != null); Contract.Requires(bodyEmitter != null); var i = il.DeclareLocal(typeof(int), "i"); il.EmitLdc_I4_0(); il.EmitAnyStloc(i); var forCond = il.DefineLabel("FOR_COND"); il.EmitBr(forCond); var body = il.DefineLabel("BODY"); il.MarkLabel(body); bodyEmitter(il, i); // increment il.EmitAnyLdloc(i); il.EmitLdc_I4_1(); il.EmitAdd(); il.EmitAnyStloc(i); // cond il.MarkLabel(forCond); il.EmitAnyLdloc(i); il.EmitAnyLdloc(count); il.EmitBlt(body); }
private static void EmitDeserializeValueCore(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember?member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder) { MethodInfo directReadMethod = _Unpacker.GetDirectReadMethod(value.LocalType); if ((directReadMethod != null) && (!member.HasValue || !UnpackHelpers.IsReadOnlyAppendableCollectionMember(member.Value.Member))) { LocalBuilder isDeserializationSucceeded = localHolder.IsDeserializationSucceeded; il.EmitLdc_I4_0(); il.EmitAnyStloc(isDeserializationSucceeded); il.BeginExceptionBlock(); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitAnyLdloca(value); il.EmitAnyCall(directReadMethod); il.EmitAnyStloc(isDeserializationSucceeded); il.BeginCatchBlock(typeof(MessageTypeException)); LocalBuilder catchedException = localHolder.GetCatchedException(typeof(MessageTypeException)); il.EmitAnyStloc(catchedException); il.EmitTypeOf(targetType); il.EmitLdstr(memberName); il.EmitAnyLdloc(catchedException); il.EmitAnyCall(SerializationExceptions.NewFailedToDeserializeMemberMethod); il.EmitThrow(); il.EndExceptionBlock(); Label target = il.DefineLabel("END_IF"); il.EmitAnyLdloc(isDeserializationSucceeded); il.EmitBrtrue_S(target); il.EmitAnyCall(SerializationExceptions.NewUnexpectedEndOfStreamMethod); il.EmitThrow(); il.MarkLabel(target); if (member.HasValue) { EmitNilImplicationForPrimitive(il, member.Value, value, endOfDeserialization); } } else { EmitGeneralRead(il, unpackerArgumentIndex); if (member.HasValue) { EmitNilImplication(il, unpackerArgumentIndex, member.Value.Contract.Name, member.Value.Contract.NilImplication, endOfDeserialization, localHolder); } Label label2 = il.DefineLabel("THEN_IF_COLLECTION"); Label label3 = il.DefineLabel("END_IF_COLLECTION"); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.IsArrayHeader); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(_Unpacker.IsMapHeader); il.EmitOr(); il.EmitBrtrue_S(label2); EmitUnpackFrom(emitter, il, value, unpackerArgumentIndex); il.EmitBr_S(label3); LocalBuilder subtreeUnpacker = localHolder.SubtreeUnpacker; il.MarkLabel(label2); EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker); EmitUnpackFrom(emitter, il, value, subtreeUnpacker); EmitUnpackerEndReadSubtree(il, subtreeUnpacker); il.MarkLabel(label3); } }
/// <summary> /// Emits the deserialize value. /// </summary> /// <param name="emitter">The emitter.</param> /// <param name="il">The il generator.</param> /// <param name="unpackerArgumentIndex">Index of the unpacker argument.</param> /// <param name="value">The value local variable which stores unpacked value.</param> /// <param name="targetType">The type of deserialzing type.</param> /// <param name="member">The metadata for nil implication. Specify <c>null</c> if nil implication is not needed.</param> /// <param name="memberName">The name of the member.</param> /// <param name="endOfDeserialization">The end of deserialization label for nil implication.</param> /// <param name="localHolder">The <see cref="LocalVariableHolder"/> which holds shared local variable information.</param> private static void EmitDeserializeValueCore(SerializerEmitter emitter, TracingILGenerator il, int unpackerArgumentIndex, LocalBuilder value, Type targetType, SerializingMember?member, string memberName, Label endOfDeserialization, LocalVariableHolder localHolder) { var directUnpacking = Metadata._Unpacker.GetDirectReadMethod(value.LocalType); if (directUnpacking != null && (member == null || !UnpackHelpers.IsReadOnlyAppendableCollectionMember(member.Value.Member))) { var isSuccess = localHolder.IsDeserializationSucceeded; il.EmitLdc_I4_0(); il.EmitAnyStloc(isSuccess); il.BeginExceptionBlock(); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitAnyLdloca(value); il.EmitAnyCall(directUnpacking); il.EmitAnyStloc(isSuccess); il.BeginCatchBlock(typeof(MessageTypeException)); var ex = localHolder.GetCatchedException(typeof(MessageTypeException)); il.EmitAnyStloc(ex); il.EmitTypeOf(targetType); il.EmitLdstr(memberName); il.EmitAnyLdloc(ex); il.EmitAnyCall(SerializationExceptions.NewFailedToDeserializeMemberMethod); il.EmitThrow(); il.EndExceptionBlock(); var endIf0 = il.DefineLabel("END_IF"); il.EmitAnyLdloc(isSuccess); il.EmitBrtrue_S(endIf0); il.EmitAnyCall(SerializationExceptions.NewUnexpectedEndOfStreamMethod); il.EmitThrow(); il.MarkLabel(endIf0); if (member != null) { // If null, nil implication is NOT needed. EmitNilImplicationForPrimitive(il, member.Value, value, endOfDeserialization); } } else { EmitGeneralRead(il, unpackerArgumentIndex); if (member != null) { // If null, nil implication is NOT needed. EmitNilImplication( il, unpackerArgumentIndex, member.Value.Contract.Name, member.Value.Contract.NilImplication, endOfDeserialization, localHolder ); } var thenIffCollection = il.DefineLabel("THEN_IF_COLLECTION"); var endIfCollection = il.DefineLabel("END_IF_COLLECTION"); /* * if( !unpacker.IsArrayHeader && !unpacker.IsMapHeader ) * { * value = GET_SERIALIZER().UnpackFrom( unpacker ); * } * else * { * using( var subtreeUnpacker = unpacker.ReadSubtree() ) * { * value = GET_SERIALIZER().UnpackFrom( subtreeUnpacker ); * } * } */ il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(Metadata._Unpacker.IsArrayHeader); il.EmitAnyLdarg(unpackerArgumentIndex); il.EmitGetProperty(Metadata._Unpacker.IsMapHeader); il.EmitOr(); il.EmitBrtrue_S(thenIffCollection); EmitUnpackFrom(emitter, il, value, unpackerArgumentIndex); il.EmitBr_S(endIfCollection); var subtreeUnpacker = localHolder.SubtreeUnpacker; il.MarkLabel(thenIffCollection); EmitUnpackerBeginReadSubtree(il, unpackerArgumentIndex, subtreeUnpacker); EmitUnpackFrom(emitter, il, value, subtreeUnpacker); EmitUnpackerEndReadSubtree(il, subtreeUnpacker); il.MarkLabel(endIfCollection); } }