Пример #1
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriterOrCtx, Action <IILGen> pushValue)
        {
            var realFinish          = ilGenerator.DefineLabel();
            var finish              = ilGenerator.DefineLabel();
            var next                = ilGenerator.DefineLabel();
            var localValue          = ilGenerator.DeclareLocal(_type !);
            var typeAsICollection   = _type.GetInterface("ICollection`1");
            var typeAsIEnumerable   = _type.GetInterface("IEnumerable`1");
            var getEnumeratorMethod = typeAsIEnumerable !.GetMethod("GetEnumerator");
            var typeAsIEnumerator   = getEnumeratorMethod !.ReturnType;
            var typeKeyValuePair    = typeAsICollection !.GetGenericArguments()[0];
            var localEnumerator     = ilGenerator.DeclareLocal(typeAsIEnumerator);
            var localPair           = ilGenerator.DeclareLocal(typeKeyValuePair);

            ilGenerator
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriterOrCtx)
            .Ldloc(localValue)
            .Castclass(typeof(object))
            .Callvirt(() => default(IWriterCtx).WriteObject(null))
            .Brfalse(realFinish)
            .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
            .Ldloc(localValue)
            .Callvirt(typeAsICollection.GetProperty("Count") !.GetGetMethod() !)
            .ConvU4()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
            .Ldloc(localValue)
            .Callvirt(getEnumeratorMethod)
            .Stloc(localEnumerator)
            .Try()
            .Mark(next)
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IEnumerator).MoveNext())
            .Brfalse(finish)
            .Ldloc(localEnumerator)
            .Callvirt(typeAsIEnumerator.GetProperty("Current") !.GetGetMethod() !)
            .Stloc(localPair);
            var keyAndValueTypes = _type.GetGenericArguments();

            _keysHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _keysHandler.NeedsCtx()), il => il
                              .Ldloca(localPair)
                              .Call(typeKeyValuePair.GetProperty("Key") !.GetGetMethod() !)
                              .Do(_typeConvertGenerator.GenerateConversion(keyAndValueTypes[0], _keysHandler.HandledType()) !));
            _valuesHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _valuesHandler.NeedsCtx()), il => il
                                .Ldloca(localPair)
                                .Call(typeKeyValuePair.GetProperty("Value") !.GetGetMethod() !)
                                .Do(_typeConvertGenerator.GenerateConversion(keyAndValueTypes[1], _valuesHandler.HandledType()) !));
            ilGenerator
            .Br(next)
            .Mark(finish)
            .Finally()
            .Ldloc(localEnumerator)
            .Callvirt(() => default(IDisposable).Dispose())
            .EndTry()
            .Mark(realFinish);
        }
Пример #2
0
        public void Save(IILGen ilGenerator, Action <IILGen> pushWriterOrCtx, Action <IILGen> pushValue)
        {
            var finish     = ilGenerator.DefineLabel();
            var next       = ilGenerator.DefineLabel();
            var localValue = ilGenerator.DeclareLocal(_type);
            var localIndex = ilGenerator.DeclareLocal(typeof(int));
            var localCount = ilGenerator.DeclareLocal(typeof(int));

            ilGenerator
            .LdcI4(0)
            .Stloc(localIndex)
            .Do(pushValue)
            .Stloc(localValue)
            .Do(pushWriterOrCtx)
            .Ldloc(localValue)
            .Castclass(typeof(object))
            .Callvirt(() => default(IWriterCtx).WriteObject(null))
            .Brfalse(finish)
            .Ldloc(localValue)
            .Callvirt(_type.GetInterface("ICollection`1").GetProperty("Count").GetGetMethod())
            .Stloc(localCount)
            .Do(Extensions.PushWriterFromCtx(pushWriterOrCtx))
            .Ldloc(localCount)
            .ConvU4()
            .Callvirt(() => default(AbstractBufferedWriter).WriteVUInt32(0))
            .Mark(next)
            .Ldloc(localIndex)
            .Ldloc(localCount)
            .BgeUn(finish);
            _itemsHandler.Save(ilGenerator, Extensions.PushWriterOrCtxAsNeeded(pushWriterOrCtx, _itemsHandler.NeedsCtx()), il => il
                               .Ldloc(localValue)
                               .Ldloc(localIndex)
                               .Callvirt(_type.GetMethod("get_Item"))
                               .Do(_typeConvertorGenerator.GenerateConversion(_type.GetGenericArguments()[0], _itemsHandler.HandledType())));
            ilGenerator
            .Ldloc(localIndex)
            .LdcI4(1)
            .Add()
            .Stloc(localIndex)
            .Br(next)
            .Mark(finish);
        }