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); }
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(); } }
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(); } }
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))); }
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); } }
internal void EndTry(CodeLabel label, bool @short) { OpCode opcode = @short ? OpCodes.Leave_S : OpCodes.Leave; this.il.Emit(opcode, label.Value); }
internal void BranchIfTrue(CodeLabel label, bool @short) { OpCode opcode = @short ? OpCodes.Brtrue_S : OpCodes.Brtrue; this.il.Emit(opcode, label.Value); }
internal void BranchIfLess(CodeLabel label, bool @short) { OpCode opcode = @short ? OpCodes.Blt_S : OpCodes.Blt; this.il.Emit(opcode, label.Value); }
internal void BranchIfEqual(CodeLabel label, bool @short) { OpCode opcode = @short ? OpCodes.Beq_S : OpCodes.Beq; this.il.Emit(opcode, label.Value); }
internal void MarkLabel(CodeLabel label) { this.il.MarkLabel(label.Value); }