Beispiel #1
0
        public void EmitDeserialize(Emit <Func <BinaryReader, object> > emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            if (_length <= 0)
            {
                emiter.Call(typeof(Array)
                            .GetMethod(nameof(Array.Empty))
                            .GetGenericMethodDefinition()
                            .MakeGenericMethod(elementType));
                emiter.StoreLocal(value);
            }
            else
            {
                // value = new [length]
                emiter.LoadConstant(_length);
                emiter.NewArray(elementType);
                emiter.StoreLocal(value);

                var loop      = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid());
                var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid());

                // Little optimization for byte arrays
                if (elementType == typeof(byte))
                {
                    // value = reader.ReadBytes(length);
                    emiter.LoadArgument(1);
                    emiter.LoadConstant(_length);
                    emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes)));
                    emiter.StoreLocal(value);
                }
                else
                {
                    using (var element = emiter.DeclareLocal(elementType, "element"))
                        using (var i = emiter.DeclareLocal <int>("i"))
                        {
                            emiter.MarkLabel(loop);
                            emiter.CallDeserializerForType(elementType, element);

                            // value[i] = element
                            emiter.LoadLocal(value);
                            emiter.LoadLocal(i);
                            emiter.LoadLocal(element);
                            emiter.StoreElement(elementType);

                            // ++i
                            emiter.LoadLocal(i);
                            emiter.LoadConstant(1);
                            emiter.Add();
                            emiter.StoreLocal(i);

                            // i < length
                            emiter.MarkLabel(loopCheck);
                            emiter.LoadLocal(i);
                            emiter.LoadConstant(_length);
                            emiter.BranchIfLess(loop);
                        }
                }
            }
        }
        public void EmitSerialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            using (var length = emiter.DeclareLocal <int>("length"))
            {
                // length = value.Length
                emiter.LoadLocal(value);
                emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod);
                emiter.StoreLocal(length);

                emiter.CallSerializerForType(length.LocalType, length);

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.Branch(loopCheck);
                        emiter.MarkLabel(loop);

                        // element = value[i]
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadElement(elementType);
                        emiter.StoreLocal(element);

                        if (_compiler != null)
                        {
                            _compiler.EmitSerialize(emiter, element);
                        }
                        else if (_serializer != null)
                        {
                            emiter.CallSerializer(_serializer, element);
                        }
                        else
                        {
                            emiter.CallSerializerForType(elementType, element);
                        }

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
            }
        }
Beispiel #3
0
        public void EmitDeserialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            //value = new Type[100];
            emiter.LoadConstant(100);
            emiter.NewArray(elementType);
            emiter.StoreLocal(value);

            var loop      = emiter.DefineLabel();
            var loopCheck = emiter.DefineLabel();

            using (var ex = emiter.DeclareLocal <Exception>("_ex"))
                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.MarkLabel(loop);

                        var eb = emiter.BeginExceptionBlock();
                        if (_compiler != null)
                        {
                            _compiler.EmitDeserialize(emiter, element);
                        }
                        else if (_serializer != null)
                        {
                            emiter.CallDeserializer(_serializer, element);
                        }
                        else
                        {
                            emiter.CallDeserializerForType(elementType, element);
                        }
                        var cb = emiter.BeginCatchBlock <Exception>(eb);
                        emiter.StoreLocal(ex);
                        emiter.EndCatchBlock(cb);
                        emiter.EndExceptionBlock(eb);

                        // value[i] = element
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(element);
                        emiter.StoreElement(elementType);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(100);
                        emiter.BranchIfLess(loop);
                    }
        }
Beispiel #4
0
        public void EmitSerialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            using (var length = emiter.DeclareLocal <int>("length"))
            {
                // length = value.Length
                emiter.LoadLocal(value);
                emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod);
                emiter.StoreLocal(length);

                emiter.CallSerializerForType(length.LocalType, length);

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.Branch(loopCheck);
                        emiter.MarkLabel(loop);

                        // element = value[i]
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadElement(elementType);
                        emiter.StoreLocal(element);

                        // writer.Write((byte)i)
                        emiter.LoadArgument(1);
                        emiter.LoadLocal(i);
                        emiter.Convert <byte>();
                        emiter.CallVirtual(typeof(BinaryWriter).GetMethod(nameof(BinaryWriter.Write),
                                                                          new[] { typeof(byte) }));

                        emiter.CallSerializerForType(elementType, element);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
            }
        }
        public void EmitSerialize(Emit emiter, Local value)
        {
            // ToDo check for null

            var elementType = value.LocalType.GetElementType();

            using (var length = emiter.DeclareLocal <int>("length"))
            {
                // length = value.Length
                emiter.LoadLocal(value);
                emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod);
                emiter.StoreLocal(length);

                // ProudNetBinaryWriterExtensions.WriteScalar(writer, length)
                emiter.LoadArgument(1);
                emiter.LoadLocal(length);
                emiter.Call(ReflectionHelper.GetMethod((BinaryWriter x) => x.WriteScalar(default(int))));

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.Branch(loopCheck);
                        emiter.MarkLabel(loop);

                        // element = value[i]
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadElement(elementType);
                        emiter.StoreLocal(element);

                        emiter.CallSerializerForType(elementType, element);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
            }
        }
        public void EmitSerialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            using (var length = emiter.DeclareLocal <short>("length"))
            {
                // length = value.Length
                emiter.LoadLocal(value);
                emiter.Call(value.LocalType.GetProperty(nameof(Array.Length)).GetMethod);
                emiter.StoreLocal(length);

                emiter.CallSerializerForType(length.LocalType, length);

                var loop      = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid());
                var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid());

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.Branch(loopCheck);
                        emiter.MarkLabel(loop);

                        // element = value[i]
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadElement(elementType);
                        emiter.StoreLocal(element);

                        emiter.CallSerializerForType(elementType, element);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
            }
        }
Beispiel #7
0
        public void EmitSerialize(Emit <Action <BinaryWriter, object> > emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();

            if (_length <= 0)
            {
                return;
            }

            var loop      = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "Loop" + Guid.NewGuid());
            var loopCheck = emiter.DefineLabel(nameof(ArrayWithScalarSerializer) + "LoopCheck" + Guid.NewGuid());

            using (var element = emiter.DeclareLocal(elementType, "element"))
                using (var i = emiter.DeclareLocal <int>("i"))
                {
                    emiter.Branch(loopCheck);
                    emiter.MarkLabel(loop);

                    // element = value[i]
                    emiter.LoadLocal(value);
                    emiter.LoadLocal(i);
                    emiter.LoadElement(elementType);
                    emiter.StoreLocal(element);

                    emiter.CallSerializerForType(elementType, element);

                    // ++i
                    emiter.LoadLocal(i);
                    emiter.LoadConstant(1);
                    emiter.Add();
                    emiter.StoreLocal(i);

                    // i < length
                    emiter.MarkLabel(loopCheck);
                    emiter.LoadLocal(i);
                    emiter.LoadConstant(_length);
                    emiter.BranchIfLess(loop);
                }
        }
        public void EmitDeserialize(Emit <Func <BinaryReader, object> > emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();
            var emptyArray  = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "EmptyArray" + Guid.NewGuid());
            var end         = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "End" + Guid.NewGuid());

            using (var length = emiter.DeclareLocal <int>("length"))
            {
                emiter.CallDeserializerForType(length.LocalType, length);

                // if(length < 1) {
                //  value = Array.Empty<>()
                //  return
                // }
                emiter.LoadLocal(length);
                emiter.LoadConstant(1);
                emiter.BranchIfLess(emptyArray);

                // value = new [length]
                emiter.LoadLocal(length);
                emiter.NewArray(elementType);
                emiter.StoreLocal(value);

                var loop      = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "Loop" + Guid.NewGuid());
                var loopCheck = emiter.DefineLabel(nameof(ArrayWithIntPrefixAndIndexSerializer) + "LoopCheck" + Guid.NewGuid());

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <int>("i"))
                    {
                        emiter.MarkLabel(loop);

                        // reader.ReadByte() -> index
                        emiter.LoadArgument(1);
                        emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadByte)));
                        emiter.Pop();

                        emiter.CallDeserializerForType(elementType, element);

                        // value[i] = element
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(element);
                        emiter.StoreElement(elementType);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
                emiter.Branch(end);
            }

            // value = Array.Empty<>()
            emiter.MarkLabel(emptyArray);
            emiter.Call(typeof(Array)
                        .GetMethod(nameof(Array.Empty))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(elementType));
            emiter.StoreLocal(value);
            emiter.MarkLabel(end);
        }
        public void EmitDeserialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();
            var emptyArray  = emiter.DefineLabel();
            var end         = emiter.DefineLabel();

            using (var length = emiter.DeclareLocal <short>("length"))
            {
                emiter.CallDeserializerForType(length.LocalType, length);

                // if(length < 1) {
                //  value = Array.Empty<>()
                //  return
                // }
                emiter.LoadLocal(length);
                emiter.LoadConstant(1);
                emiter.BranchIfLess(emptyArray);

                // value = new [length]
                emiter.LoadLocal(length);
                emiter.NewArray(elementType);
                emiter.StoreLocal(value);

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                // Little optimization for byte arrays
                if (elementType == typeof(byte))
                {
                    // value = reader.ReadBytes(length);
                    emiter.LoadArgument(1);
                    emiter.LoadLocal(length);
                    emiter.CallVirtual(typeof(BinaryReader).GetMethod(nameof(BinaryReader.ReadBytes)));
                    emiter.StoreLocal(value);
                    emiter.Branch(end);
                }
                else
                {
                    using (var element = emiter.DeclareLocal(elementType, "element"))
                        using (var i = emiter.DeclareLocal <int>("i"))
                        {
                            emiter.MarkLabel(loop);
                            emiter.CallDeserializerForType(elementType, element);

                            // value[i] = element
                            emiter.LoadLocal(value);
                            emiter.LoadLocal(i);
                            emiter.LoadLocal(element);
                            emiter.StoreElement(elementType);

                            // ++i
                            emiter.LoadLocal(i);
                            emiter.LoadConstant(1);
                            emiter.Add();
                            emiter.StoreLocal(i);

                            // i < length
                            emiter.MarkLabel(loopCheck);
                            emiter.LoadLocal(i);
                            emiter.LoadLocal(length);
                            emiter.BranchIfLess(loop);
                        }
                }

                emiter.Branch(end);
            }

            // value = Array.Empty<>()
            emiter.MarkLabel(emptyArray);
            emiter.Call(typeof(Array)
                        .GetMethod(nameof(Array.Empty))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(elementType));
            emiter.StoreLocal(value);
            emiter.MarkLabel(end);
        }
Beispiel #10
0
        public void EmitDeserialize(Emit emiter, Local value)
        {
            var elementType = value.LocalType.GetElementType();
            var emptyArray  = emiter.DefineLabel();
            var end         = emiter.DefineLabel();

            using (var length = emiter.DeclareLocal <T>("length"))
            {
                emiter.CallDeserializerForType(length.LocalType, length);

                // if(length < 1) {
                //  value = Array.Empty<>()
                //  return
                // }
                emiter.LoadLocal(length);
                emiter.LoadConstant(1);
                emiter.BranchIfLess(emptyArray);

                // value = new [length]
                emiter.LoadLocal(length);
                emiter.NewArray(elementType);
                emiter.StoreLocal(value);

                var loop      = emiter.DefineLabel();
                var loopCheck = emiter.DefineLabel();

                using (var element = emiter.DeclareLocal(elementType, "element"))
                    using (var i = emiter.DeclareLocal <T>("i"))
                    {
                        emiter.MarkLabel(loop);

                        if (_compiler != null)
                        {
                            _compiler.EmitDeserialize(emiter, element);
                        }
                        else if (_serializer != null)
                        {
                            emiter.CallDeserializer(_serializer, element);
                        }
                        else
                        {
                            emiter.CallDeserializerForType(elementType, element);
                        }

                        // value[i] = element
                        emiter.LoadLocal(value);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(element);
                        emiter.StoreElement(elementType);

                        // ++i
                        emiter.LoadLocal(i);
                        emiter.LoadConstant(1);
                        emiter.Add();
                        emiter.StoreLocal(i);

                        // i < length
                        emiter.MarkLabel(loopCheck);
                        emiter.LoadLocal(i);
                        emiter.LoadLocal(length);
                        emiter.BranchIfLess(loop);
                    }
                emiter.Branch(end);
            }

            // value = Array.Empty<>()
            emiter.MarkLabel(emptyArray);
            emiter.Call(typeof(Array)
                        .GetMethod(nameof(Array.Empty))
                        .GetGenericMethodDefinition()
                        .MakeGenericMethod(elementType));
            emiter.StoreLocal(value);
            emiter.MarkLabel(end);
        }