private static void EmitUnpackMembers(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result) { /* * #if T is IUnpackable * result.UnpackFromMessage( unpacker ); * #else * if( unpacker.IsArrayHeader ) * { * ... * } * else * { * ... * } * #endif */ var localHolder = new LocalVariableHolder(unpackerIL); unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitGetProperty(Metadata._Unpacker.IsArrayHeader); var @else = unpackerIL.DefineLabel("ELSE"); var endif = unpackerIL.DefineLabel("END_IF"); unpackerIL.EmitBrfalse(@else); EmitUnpackMembersFromArray(emitter, unpackerIL, entries, result, localHolder, endif); unpackerIL.EmitBr(endif); unpackerIL.MarkLabel(@else); EmitUnpackMembersFromMap(emitter, unpackerIL, entries, result, localHolder); unpackerIL.MarkLabel(endif); }
private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder) { Label label = unpackerIL.DefineLabel("BEGIN_LOOP"); Label target = unpackerIL.DefineLabel("END_LOOP"); unpackerIL.MarkLabel(label); LocalBuilder memberName = localHolder.MemberName; unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitAnyLdloca(memberName); unpackerIL.EmitAnyCall(_Unpacker.ReadString); unpackerIL.EmitBrfalse(target); LocalBuilder unpackedData = localHolder.UnpackedData; LocalBuilder unpackedDataValue = localHolder.UnpackedDataValue; for (int i = 0; i < entries.Length; i++) { if (entries[i].Contract.Name != null) { unpackerIL.EmitAnyLdloc(memberName); unpackerIL.EmitLdstr(entries[i].Contract.Name); unpackerIL.EmitAnyCall(_String.op_Equality); Label label3 = unpackerIL.DefineLabel("END_IF_MEMBER_" + i); unpackerIL.EmitBrfalse(label3); if (entries[i].Member == null) { Emittion.EmitGeneralRead(unpackerIL, 1); } else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member)) { Emittion.EmitDeserializeCollectionValue(emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder); } else { Emittion.EmitDeserializeValue(emitter, unpackerIL, 1, result, entries[i], localHolder); } unpackerIL.EmitBr(label); unpackerIL.MarkLabel(label3); } } unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitCallvirt(_Unpacker.Read); unpackerIL.EmitPop(); unpackerIL.EmitBr(label); unpackerIL.MarkLabel(target); }
public override void Branch(TracingILGenerator il, Label @else) { il.TraceWriteLine("// Brnc->: {0}", this); foreach (var expression in this._expressions) { expression.LoadValue(il, false); il.EmitBrfalse(@else); } il.TraceWriteLine("// ->Brnc: {0}", this); }
private static void EmitUnpackMembers(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result) { LocalVariableHolder localHolder = new LocalVariableHolder(unpackerIL); unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitGetProperty(_Unpacker.IsArrayHeader); Label target = unpackerIL.DefineLabel("ELSE"); Label label2 = unpackerIL.DefineLabel("END_IF"); unpackerIL.EmitBrfalse(target); EmittingSerializerBuilder <TObject> .EmitUnpackMembersFromArray(emitter, unpackerIL, entries, result, localHolder); unpackerIL.EmitBr(label2); unpackerIL.MarkLabel(target); EmittingSerializerBuilder <TObject> .EmitUnpackMembersFromMap(emitter, unpackerIL, entries, result, localHolder); unpackerIL.MarkLabel(label2); }
protected virtual void BranchCore(TracingILGenerator il, Label @else) { this.LoadValue(il, false); il.EmitBrfalse(@else); }
public static void EmitForEach(TracingILGenerator il, CollectionTraits traits, LocalBuilder collection, Action <TracingILGenerator, Action> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(collection != null); Contract.Requires(bodyEmitter != null); LocalBuilder enumerator = il.DeclareLocal(traits.GetEnumeratorMethod.ReturnType, "enumerator"); if (collection.LocalType.IsValueType) { il.EmitAnyLdloca(collection); } else { il.EmitAnyLdloc(collection); } il.EmitAnyCall(traits.GetEnumeratorMethod); il.EmitAnyStloc(enumerator); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginExceptionBlock(); } Label label = il.DefineLabel("START_LOOP"); il.MarkLabel(label); Label target = il.DefineLabel("END_LOOP"); Type returnType = traits.GetEnumeratorMethod.ReturnType; MethodInfo method = returnType.GetMethod("MoveNext", Type.EmptyTypes); PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty("Current"); if (method == null) { method = _IEnumerator.MoveNext; } if (currentProperty == null) { if (returnType == typeof(IDictionaryEnumerator)) { currentProperty = _IDictionaryEnumerator.Current; } else if (returnType.IsInterface) { if (returnType.IsGenericType && (returnType.GetGenericTypeDefinition() == typeof(IEnumerator <>))) { currentProperty = typeof(IEnumerator <>).MakeGenericType(new Type[] { traits.ElementType }).GetProperty("Current"); } else { currentProperty = _IEnumerator.Current; } } } Contract.Assert(currentProperty != null, returnType.ToString()); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitAnyCall(method); il.EmitBrfalse(target); bodyEmitter(il, delegate { if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitGetProperty(currentProperty); }); il.EmitBr(label); il.MarkLabel(target); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginFinallyBlock(); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { MethodInfo info2 = traits.GetEnumeratorMethod.ReturnType.GetMethod("Dispose"); if (((info2 != null) && (info2.GetParameters().Length == 0)) && (info2.ReturnType == typeof(void))) { il.EmitAnyLdloca(enumerator); il.EmitAnyCall(info2); } else { il.EmitAnyLdloc(enumerator); il.EmitBox(traits.GetEnumeratorMethod.ReturnType); il.EmitAnyCall(_IDisposable.Dispose); } } else { il.EmitAnyLdloc(enumerator); il.EmitAnyCall(_IDisposable.Dispose); } il.EndExceptionBlock(); } }
/// <summary> /// Emits 'foreach' statement on the IL stream. /// </summary> /// <param name="il">IL generator to be emitted to.</param> /// <param name="traits"><see cref="CollectionTraits"/> which contains traits of the iterating collection.</param> /// <param name="collection">'collection' argument index.</param> /// <param name="bodyEmitter">Delegate to emit body statement.</param> public static void EmitForEach(TracingILGenerator il, CollectionTraits traits, LocalBuilder collection, Action <TracingILGenerator, Action> bodyEmitter) { Contract.Requires(il != null); Contract.Requires(collection != null); Contract.Requires(bodyEmitter != null); var enumerator = il.DeclareLocal(traits.GetEnumeratorMethod.ReturnType, "enumerator"); // gets enumerator if (collection.LocalType.IsValueType) { il.EmitAnyLdloca(collection); } else { il.EmitAnyLdloc(collection); } il.EmitAnyCall(traits.GetEnumeratorMethod); il.EmitAnyStloc(enumerator); if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginExceptionBlock(); } var startLoop = il.DefineLabel("START_LOOP"); il.MarkLabel(startLoop); var endLoop = il.DefineLabel("END_LOOP"); var enumeratorType = traits.GetEnumeratorMethod.ReturnType; MethodInfo moveNextMethod = enumeratorType.GetMethod("MoveNext", Type.EmptyTypes); PropertyInfo currentProperty = traits.GetEnumeratorMethod.ReturnType.GetProperty("Current"); if (moveNextMethod == null) { moveNextMethod = Metadata._IEnumerator.MoveNext; } if (currentProperty == null) { if (enumeratorType == typeof(IDictionaryEnumerator)) { currentProperty = Metadata._IDictionaryEnumerator.Current; } else if (enumeratorType.IsInterface) { if (enumeratorType.IsGenericType && enumeratorType.GetGenericTypeDefinition() == typeof(IEnumerator <>)) { currentProperty = typeof(IEnumerator <>).MakeGenericType(traits.ElementType).GetProperty("Current"); } else { currentProperty = Metadata._IEnumerator.Current; } } } Contract.Assert(currentProperty != null, enumeratorType.ToString()); // iterates if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitAnyCall(moveNextMethod); il.EmitBrfalse(endLoop); bodyEmitter( il, () => { if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { il.EmitAnyLdloca(enumerator); } else { il.EmitAnyLdloc(enumerator); } il.EmitGetProperty(currentProperty); } ); il.EmitBr(startLoop); il.MarkLabel(endLoop); // Dispose if (typeof(IDisposable).IsAssignableFrom(traits.GetEnumeratorMethod.ReturnType)) { il.BeginFinallyBlock(); if (traits.GetEnumeratorMethod.ReturnType.IsValueType) { var disposeMethod = traits.GetEnumeratorMethod.ReturnType.GetMethod("Dispose"); if (disposeMethod != null && disposeMethod.GetParameters().Length == 0 && disposeMethod.ReturnType == typeof(void)) { il.EmitAnyLdloca(enumerator); il.EmitAnyCall(disposeMethod); } else { il.EmitAnyLdloc(enumerator); il.EmitBox(traits.GetEnumeratorMethod.ReturnType); il.EmitAnyCall(Metadata._IDisposable.Dispose); } } else { il.EmitAnyLdloc(enumerator); il.EmitAnyCall(Metadata._IDisposable.Dispose); } il.EndExceptionBlock(); } }
private static void EmitUnpackMembersFromMap(SerializerEmitter emitter, TracingILGenerator unpackerIL, SerializingMember[] entries, LocalBuilder result, LocalVariableHolder localHolder) { /* * var memberName = unpacker.Data.AsString(); * if( memberName == "A" ) * { * if( !unpacker.Read() ) * { * throw SerializationExceptions.NewUnexpectedStreamEndsException(); * } * * isAFound = true; * } * : */ var beginLoop = unpackerIL.DefineLabel("BEGIN_LOOP"); var endLoop = unpackerIL.DefineLabel("END_LOOP"); unpackerIL.MarkLabel(beginLoop); var memberName = localHolder.MemberName; unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitAnyLdloca(memberName); unpackerIL.EmitAnyCall(Metadata._Unpacker.ReadString); unpackerIL.EmitBrfalse(endLoop); for (int i = 0; i < entries.Length; i++) { if (entries[i].Contract.Name == null) { // skip undefined member continue; } // TODO: binary comparison // Is it current member? unpackerIL.EmitAnyLdloc(memberName); unpackerIL.EmitLdstr(entries[i].Contract.Name); unpackerIL.EmitAnyCall(Metadata._String.op_Equality); var endIfCurrentMember = unpackerIL.DefineLabel("END_IF_MEMBER_" + i); unpackerIL.EmitBrfalse(endIfCurrentMember); // Deserialize value if (entries[i].Member == null) { Emittion.EmitGeneralRead(unpackerIL, 1); // Ignore undefined member -- Nop. } else if (UnpackHelpers.IsReadOnlyAppendableCollectionMember(entries[i].Member)) { Emittion.EmitDeserializeCollectionValue( emitter, unpackerIL, 1, result, entries[i].Member, entries[i].Member.GetMemberValueType(), entries[i].Contract.NilImplication, localHolder ); } else { Emittion.EmitDeserializeValue( emitter, unpackerIL, 1, result, entries[i], localHolder ); } // TOOD: Record for missing check unpackerIL.EmitBr(beginLoop); unpackerIL.MarkLabel(endIfCurrentMember); } // Drain next value with unpacker.Read() unpackerIL.EmitAnyLdarg(1); unpackerIL.EmitCallvirt(Metadata._Unpacker.Read); unpackerIL.EmitPop(); unpackerIL.EmitBr(beginLoop); unpackerIL.MarkLabel(endLoop); }
private static void BranchWithOperationResult(ILConstruct input, Action <TracingILGenerator, ILConstruct> operation, TracingILGenerator il, Label @else) { operation(il, input); il.EmitBrfalse(@else); }