public LabelWrapper DefineLabel() { var label = new LabelWrapper(); this.AddInstruction(new ILInstruction(OpCodes.Nop, label, typeof(LabelWrapper), ILInstructionType.DefineLabel)); return(label); }
public void EmitBreak(OpCode opcode, LabelWrapper label) { if (!opcode.Name.StartsWith("b") || opcode == OpCodes.Break || opcode == OpCodes.Box) { throw new Exception("Unsupported Opcode, only 'break'-opcodes supported"); } this.AddInstruction(opcode, label); }
public void EmitSwitchCases(Type switchType, Type returnType, List <Tuple <object, object> > switchReturnValues) { var defaultCase = this.DefineLabel(); var endOfMethod = this.DefineLabel(); var switchValue = this.DeclareLocal(switchType); this.EmitLocal(OpCodes.Stloc, switchValue); var jumpTable = new LabelWrapper[switchReturnValues.Count]; for (int i = 0; i < switchReturnValues.Count; i++) { jumpTable[i] = this.DefineLabel(); this.EmitLocal(OpCodes.Ldloc, switchValue); this.EmitLoadEnumValue(switchType, switchReturnValues[i].Item1); if (switchType == typeof(string)) { var stringEquals = typeof(string).GetMethod("op_Equality", new[] { typeof(string), typeof(string) }); this.EmitCall(OpCodes.Call, stringEquals); this.Emit(OpCodes.Ldc_I4_1); } this.EmitBreak(OpCodes.Beq, jumpTable[i]); } // Branch on default case this.EmitBreak(OpCodes.Br, defaultCase); for (int i = 0; i < switchReturnValues.Count; i++) { this.MarkLabel(jumpTable[i]); this.EmitLoadEnumValue(returnType, switchReturnValues[i].Item2); this.EmitBreak(OpCodes.Br, endOfMethod); } // Default case this.MarkLabel(defaultCase); this.EmitLoadEnumValue(returnType, switchReturnValues[0].Item2); this.MarkLabel(endOfMethod); }
private void AddInstruction(OpCode opcode, LabelWrapper label) { this.AddInstruction(new ILInstruction(opcode, label, typeof(LabelWrapper))); }
public void MarkLabel(LabelWrapper label) { this.AddInstruction(new ILInstruction(OpCodes.Nop, label, typeof(LabelWrapper), ILInstructionType.MarkLabel)); }