public LocalBuilderWrapper DeclareLocal(Type type) { var local = new LocalBuilderWrapper(type); AddInstruction(new ILInstruction(OpCodes.Nop, local, typeof(LocalBuilderWrapper), ILInstructionType.DeclareLocal)); return(local); }
public void EmitLocal(OpCode opcode, LocalBuilderWrapper local) { if (opcode == OpCodes.Ldloc || opcode == OpCodes.Stloc || opcode == OpCodes.Ldloca) { this.AddInstruction(opcode, local); } else { throw new Exception("Unsupported Opcode, only Ldloc, Ldloca and Stloc supported"); } }
public void EmitMemberMap(LocalBuilderWrapper fromLocal, LocalBuilderWrapper toLocal, MemberMap memberMap, HashSet <Type> convertedTypes) { var skipMemberMap = this.DefineLabel(); if (memberMap.FromMember.NeedsContainsCheck) { var containsKey = fromLocal.LocalType.GetMethod("ContainsKey", new[] { typeof(string) }); this.EmitLocal(fromLocal.LocalType.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc, fromLocal); this.EmitString(memberMap.FromMember.Name); this.EmitCall(OpCodes.Call, containsKey); this.EmitBreak(OpCodes.Brfalse, skipMemberMap); } // Load toLocal as parameter for the setter this.EmitLocal(toLocal.LocalType.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc, toLocal); if (memberMap.ToMember.NeedsStringIndex) { this.EmitString(memberMap.ToMember.Name); } // Load fromLocal as parameter for the getter this.EmitLocal(fromLocal.LocalType.IsValueType ? OpCodes.Ldloca : OpCodes.Ldloc, fromLocal); if (memberMap.FromMember.MemberInfo is PropertyInfo) { var getter = (memberMap.FromMember.MemberInfo as PropertyInfo).GetGetMethod(); if (memberMap.FromMember.MemberType == MemberType.StringIndexer) { this.EmitString(memberMap.FromMember.Name); } this.EmitCall(OpCodes.Callvirt, getter); } else if (memberMap.FromMember.MemberInfo is FieldInfo) { this.EmitField(OpCodes.Ldfld, memberMap.FromMember.MemberInfo as FieldInfo); } else if (memberMap.FromMember.MemberInfo is MethodInfo) { var method = memberMap.FromMember.MemberInfo as MethodInfo; if (memberMap.FromMember.NeedsStringIndex) { this.EmitString(memberMap.FromMember.Name); } this.EmitCall(OpCodes.Callvirt, method); } // Convert the value on top of the stack to the correct toType this.EmitConvertValue(memberMap.FromMember.Type, memberMap.ToMember.Type, new HashSet <Type>(convertedTypes)); if (memberMap.ToMember.MemberInfo is PropertyInfo) { var setter = (memberMap.ToMember.MemberInfo as PropertyInfo).GetSetMethod(); this.EmitCall(OpCodes.Callvirt, setter); } else if (memberMap.ToMember.MemberInfo is FieldInfo) { this.EmitField(OpCodes.Stfld, memberMap.ToMember.MemberInfo as FieldInfo); } else if (memberMap.ToMember.MemberInfo is MethodInfo) { this.EmitCall(OpCodes.Call, memberMap.ToMember.MemberInfo as MethodInfo); } if (memberMap.FromMember.NeedsContainsCheck) { this.MarkLabel(skipMemberMap); } }
private void AddInstruction(OpCode opcode, LocalBuilderWrapper local) { AddInstruction(new ILInstruction(opcode, local, typeof(LocalBuilderWrapper))); }