protected override bool CheckEmpty(SizeCounterMethodBuilderContext context, GroboIL.Label notEmptyLabel)
 {
     context.LoadObjByRef();                                       // stack: [&obj]
     context.Il.Call(Type.GetProperty("HasValue").GetGetMethod()); // stack: obj.HasValue
     context.Il.Brtrue(notEmptyLabel);                             // if(obj.HasValue) goto notEmpty;
     return(true);
 }
Ejemplo n.º 2
0
        protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext context)
        {
            var il = context.Il;

            il.Ldc_I4(9); // stack: [9 = size] 9 = type code + data length + array length

            var doneLabel = il.DefineLabel("done");

            context.LoadObjByRef(); // stack: [size, ref obj]
            il.Ldfld(countField);   // stack: [size, obj._count]
            il.Brfalse(doneLabel);  // if(obj._count == 0) goto done; stack: [size]
            var i   = il.DeclareLocal(typeof(int));
            var end = il.DeclareLocal(typeof(int));

            context.LoadObjByRef(); // stack: [size, ref obj]
            il.Dup();               // stack: [size, ref obj, ref obj]
            il.Ldfld(offsetField);  // stack: [size, ref obj, obj._offset]
            il.Stloc(i);            // i = obj._offset; stack: [size, ref obj]
            il.Ldfld(countField);   // stack: [size, obj._count]
            il.Ldloc(i);            // stack: [size, obj._count, obj._offset]
            il.Add();               // stack: [size, obj._count + obj._offset]
            il.Stloc(end);          // end = obj._count + obj._offset; stack: [size]
            var array = il.DeclareLocal(elementType.MakeArrayType());

            context.LoadObjByRef(); // stack: [size, ref obj]
            il.Ldfld(arrayField);   // stack: [size, obj._array]
            il.Stloc(array);        // array = obj._array; stack: [size]
            var cycleStartLabel = il.DefineLabel("cycleStart");

            il.MarkLabel(cycleStartLabel);
            il.Ldloc(array);                      // stack: [size, array]
            il.Ldloc(i);                          // stack: [size, array, i]
            il.Ldelem(elementType);               // stack: [size, array[i]]
            il.Ldc_I4(1);                         // stack: [size, array[i], true]
            context.LoadContext();                // stack: [size, array[i], true, context]
            context.CallSizeCounter(elementType); // stack: [size, writer(array[i], true, context) = itemSize]
            il.Add();                             // stack: [size + itemSize]
            il.Ldloc(end);                        // stack: [size, end]
            il.Ldloc(i);                          // stack: [size, end, i]
            il.Ldc_I4(1);                         // stack: [size, end, i, 1]
            il.Add();                             // stack: [size, end, i + 1]
            il.Dup();                             // stack: [size, end, i + 1, i + 1]
            il.Stloc(i);                          // i = i + 1; stack: [size, end, i]
            il.Bgt(cycleStartLabel, false);       // if(end > i) goto cycleStart; stack: [size]
            il.MarkLabel(doneLabel);
        }
        protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext context)
        {
            var il = context.Il;

            il.Ldc_I4(5);                    // stack: [5 = size] 5 = type code + data length
            context.LoadObjByRef();          // stack: [5, ref obj]
            il.Ldfld(countField);            // stack: [5, obj._count]
            CountArraySize(elementType, il); // stack: [5, obj length]
            il.Add();                        // stack: [5 + obj length]
        }
        protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext context)
        {
            var il = context.Il;

            context.LoadObjByRef();                                 // stack: [&obj]
            il.Call(Type.GetProperty("Value").GetGetMethod());      // stack: [obj.Value]
            context.LoadWriteEmpty();                               // stack: [obj.Value, writeEmpty]
            context.LoadContext();                                  // stack: [obj.Value, writeEmpty, context]
            context.CallSizeCounter(Type.GetGenericArguments()[0]); // stack: [counter(obj.Value, writeEmpty, context)]
        }
Ejemplo n.º 5
0
        protected override bool CheckEmpty(SizeCounterMethodBuilderContext context, GroboIL.Label notEmptyLabel)
        {
            var il = context.Il;

            context.LoadObjByRef(); // stack: [ref obj]
            il.Ldfld(arrayField);   // stack: [obj._array]
            if (context.Context.GroBufWriter.Options.HasFlag(GroBufOptions.WriteEmptyObjects))
            {
                il.Brtrue(notEmptyLabel); // if(obj._array != null) goto notEmpty;
            }
            else
            {
                var emptyLabel = il.DefineLabel("empty");
                il.Brfalse(emptyLabel);   // if(obj._array == null) goto empty;
                context.LoadObjByRef();   // stack: [ref obj]
                il.Ldfld(countField);     // stack: [obj._count]
                il.Brtrue(notEmptyLabel); // if(obj._count != 0) goto notEmpty;
                il.MarkLabel(emptyLabel);
            }
            return(true);
        }
Ejemplo n.º 6
0
        protected override void CountSizeNotEmpty(SizeCounterMethodBuilderContext context)
        {
            var il = context.Il;

            il.Ldc_I4(0); // stack: [0 = size]

            var dataMembers = context.Context.GetDataMembers(Type);

            foreach (var member in dataMembers)
            {
                if (Type.IsValueType)
                {
                    context.LoadObjByRef(); // stack: [size, ref obj]
                }
                else
                {
                    context.LoadObj(); // stack: [size, obj]
                }
                Type memberType;
                switch (member.Member.MemberType)
                {
                case MemberTypes.Property:
                    var property = (PropertyInfo)member.Member;
                    var getter   = property.GetGetMethod(true);
                    if (getter == null)
                    {
                        throw new MissingMethodException(Type.Name, property.Name + "_get");
                    }
                    il.Call(getter, Type); // stack: [size, obj.prop]
                    memberType = property.PropertyType;
                    break;

                case MemberTypes.Field:
                    var field = (FieldInfo)member.Member;
                    il.Ldfld(field); // stack: [size, obj.field]
                    memberType = field.FieldType;
                    break;

                default:
                    throw new NotSupportedException("Data member of type " + member.Member.MemberType + " is not supported");
                }
                il.Ldc_I4(0);                        // stack: [size, obj.member, false]
                context.LoadContext();               // stack: [size, obj.member, false, context]
                context.CallSizeCounter(memberType); // stack: [size, writers[i](obj.member, false, context) = memberSize]
                il.Dup();                            // stack: [size, memberSize, memberSize]
                var nextLabel = il.DefineLabel("next");
                il.Brfalse(nextLabel);               // if(memberSize = 0) goto next; stack: [size, memberSize]

                il.Ldc_I4(8);                        // stack: [size, memberSize, 8]
                il.Add();                            // stack: [size, memberSize + 8]
                il.MarkLabel(nextLabel);
                il.Add();                            // stack: [size + curSize]
            }

            if (!context.Context.GroBufWriter.Options.HasFlag(GroBufOptions.WriteEmptyObjects))
            {
                var countLengthLabel = il.DefineLabel("countLength");
                il.Dup();                    // stack: [size, size]
                il.Brtrue(countLengthLabel); // if(size != 0) goto countLength; stack: [size]
                il.Pop();                    // stack: []
                context.ReturnForNull();
                il.Ret();
                il.MarkLabel(countLengthLabel);
            }
            il.Ldc_I4(5); // stack: [size, 5]
            il.Add();     // stack: [size + 5]
        }