예제 #1
0
        internal void WriteNullCheckedTail(Type type, IProtoSerializer tail, Local valueFrom)
        {
            if (type.IsValueType)
            {
                if (Helpers.GetUnderlyingType(type) == null)
                {
                    tail.EmitWrite(this, valueFrom);
                    return;
                }
                using (Local local = this.GetLocalWithValue(type, valueFrom))
                {
                    this.LoadAddress(local, type);
                    this.LoadValue(type.GetProperty("HasValue"));
                    CodeLabel label = this.DefineLabel();
                    this.BranchIfFalse(label, false);
                    this.LoadAddress(local, type);
                    this.EmitCall(type.GetMethod("GetValueOrDefault", Helpers.EmptyTypes));
                    tail.EmitWrite(this, null);
                    this.MarkLabel(label);
                    return;
                }
            }
            this.LoadValue(valueFrom);
            this.CopyValue();
            CodeLabel label2 = this.DefineLabel();
            CodeLabel label3 = this.DefineLabel();

            this.BranchIfTrue(label2, true);
            this.DiscardValue();
            this.Branch(label3, false);
            this.MarkLabel(label2);
            tail.EmitWrite(this, null);
            this.MarkLabel(label3);
        }
예제 #2
0
 public void Dispose()
 {
     if ((this.local != null) && (this.ctx != null))
     {
         this.ctx.EndTry(this.label, false);
         this.ctx.BeginFinally();
         Type       type   = this.ctx.MapType(typeof(IDisposable));
         MethodInfo method = type.GetMethod("Dispose");
         Type       type2  = this.local.Type;
         if (type2.IsValueType)
         {
             this.ctx.LoadAddress(this.local, type2);
             if (this.ctx.MetadataVersion == CompilerContext.ILVersion.Net1)
             {
                 this.ctx.LoadValue(this.local);
                 this.ctx.CastToObject(type2);
             }
             else
             {
                 this.ctx.Constrain(type2);
             }
             this.ctx.EmitCall(method);
         }
         else
         {
             CodeLabel label = this.ctx.DefineLabel();
             if (type.IsAssignableFrom(type2))
             {
                 this.ctx.LoadValue(this.local);
                 this.ctx.BranchIfFalse(label, true);
                 this.ctx.LoadAddress(this.local, type2);
             }
             else
             {
                 using (Local local = new Local(this.ctx, type))
                 {
                     this.ctx.LoadValue(this.local);
                     this.ctx.TryCast(type);
                     this.ctx.CopyValue();
                     this.ctx.StoreValue(local);
                     this.ctx.BranchIfFalse(label, true);
                     this.ctx.LoadAddress(local, type);
                 }
             }
             this.ctx.EmitCall(method);
             this.ctx.MarkLabel(label);
         }
         this.ctx.EndFinally();
         this.local = null;
         this.ctx   = null;
         this.label = new CodeLabel();
     }
 }
예제 #3
0
            public UsingBlock(CompilerContext ctx, Local local)
            {
                if (ctx == null)
                {
                    throw new ArgumentNullException("ctx");
                }
                if (local == null)
                {
                    throw new ArgumentNullException("local");
                }
                Type c = local.Type;

                if ((!c.IsValueType && !c.IsSealed) || ctx.MapType(typeof(IDisposable)).IsAssignableFrom(c))
                {
                    this.local = local;
                    this.ctx   = ctx;
                    this.label = ctx.BeginTry();
                }
            }
예제 #4
0
        public static ProtoDeserializer BuildDeserializer(IProtoSerializer head, TypeModel model)
        {
            Type            expectedType = head.ExpectedType;
            CompilerContext ctx          = new CompilerContext(expectedType, false, true, model, typeof(object));

            using (Local local = new Local(ctx, expectedType))
            {
                if (!expectedType.IsValueType)
                {
                    ctx.LoadValue(ctx.InputValue);
                    ctx.CastFromObject(expectedType);
                    ctx.StoreValue(local);
                }
                else
                {
                    ctx.LoadValue(ctx.InputValue);
                    CodeLabel label  = ctx.DefineLabel();
                    CodeLabel label2 = ctx.DefineLabel();
                    ctx.BranchIfTrue(label, true);
                    ctx.LoadAddress(local, expectedType);
                    ctx.EmitCtor(expectedType);
                    ctx.Branch(label2, true);
                    ctx.MarkLabel(label);
                    ctx.LoadValue(ctx.InputValue);
                    ctx.CastFromObject(expectedType);
                    ctx.StoreValue(local);
                    ctx.MarkLabel(label2);
                }
                head.EmitRead(ctx, local);
                if (head.ReturnsValue)
                {
                    ctx.StoreValue(local);
                }
                ctx.LoadValue(local);
                ctx.CastToObject(expectedType);
            }
            ctx.Emit(OpCodes.Ret);
            return((ProtoDeserializer)ctx.method.CreateDelegate(typeof(ProtoDeserializer)));
        }
예제 #5
0
 internal void LoadLength(Local arr, bool zeroIfNull)
 {
     if (zeroIfNull)
     {
         CodeLabel label  = this.DefineLabel();
         CodeLabel label2 = this.DefineLabel();
         this.LoadValue(arr);
         this.CopyValue();
         this.BranchIfTrue(label, true);
         this.DiscardValue();
         this.LoadValue(0);
         this.Branch(label2, true);
         this.MarkLabel(label);
         this.Emit(OpCodes.Ldlen);
         this.Emit(OpCodes.Conv_I4);
         this.MarkLabel(label2);
     }
     else
     {
         this.LoadValue(arr);
         this.Emit(OpCodes.Ldlen);
         this.Emit(OpCodes.Conv_I4);
     }
 }
예제 #6
0
        internal void EndTry(CodeLabel label, bool @short)
        {
            OpCode opcode = @short ? OpCodes.Leave_S : OpCodes.Leave;

            this.il.Emit(opcode, label.Value);
        }
예제 #7
0
        internal void BranchIfTrue(CodeLabel label, bool @short)
        {
            OpCode opcode = @short ? OpCodes.Brtrue_S : OpCodes.Brtrue;

            this.il.Emit(opcode, label.Value);
        }
예제 #8
0
        internal void BranchIfLess(CodeLabel label, bool @short)
        {
            OpCode opcode = @short ? OpCodes.Blt_S : OpCodes.Blt;

            this.il.Emit(opcode, label.Value);
        }
예제 #9
0
        internal void BranchIfEqual(CodeLabel label, bool @short)
        {
            OpCode opcode = @short ? OpCodes.Beq_S : OpCodes.Beq;

            this.il.Emit(opcode, label.Value);
        }
예제 #10
0
 internal void MarkLabel(CodeLabel label)
 {
     this.il.MarkLabel(label.Value);
 }