Beispiel #1
0
        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);
        }
Beispiel #5
0
 protected virtual void BranchCore(TracingILGenerator il, Label @else)
 {
     this.LoadValue(il, false);
     il.EmitBrfalse(@else);
 }
Beispiel #6
0
        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();
            }
        }
Beispiel #7
0
        /// <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();
            }
        }
Beispiel #8
0
        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);
 }