private void AdvanceOffsetWithLabel(OpCode opcode) { AdvanceOffset(opcode); if (OpCodes.TakesSingleByteArgument(opcode)) { _offset++; } else { _offset += 4; } }
internal ILInstruction(OpCode opCode, byte[] ilCode, int index, Module manifest) { this.OpCode = opCode; this.HasArgument = (opCode.OperandType != OperandType.InlineNone); this.HasSingleByteArgument = (OpCodes.TakesSingleByteArgument(opCode) && this.OpCode != OpCodes.Ldc_R4); this.Length = opCode.Size + (this.HasArgument ? (this.HasSingleByteArgument ? 1 : 4) : 0); if (this.HasArgument) { if (this.HasSingleByteArgument) { this.Argument = ilCode[index + opCode.Size]; } else if (this.OpCode == OpCodes.Ldc_R4) { this.Argument = BitConverter.ToSingle(ilCode, index + opCode.Size); } else { this.Argument = BitConverter.ToInt32(ilCode, index + opCode.Size); } if (this.OpCode == OpCodes.Ldstr) { this.Argument = manifest.ResolveString((int)this.Argument); return; } if (this.OpCode == OpCodes.Call || this.OpCode == OpCodes.Callvirt || this.OpCode == OpCodes.Ldftn || this.OpCode == OpCodes.Newobj) { this.Argument = manifest.ResolveMethod((int)this.Argument); return; } if (this.OpCode == OpCodes.Box || this.OpCode == OpCodes.Newarr) { this.Argument = manifest.ResolveType((int)this.Argument); return; } if (this.OpCode == OpCodes.Ldfld || this.OpCode == OpCodes.Stfld || this.OpCode == OpCodes.Ldflda || this.OpCode == OpCodes.Ldsfld || this.OpCode == OpCodes.Stsfld || this.OpCode == OpCodes.Ldsflda) { this.Argument = manifest.ResolveField((int)this.Argument); return; } } else { this.Argument = null; } }
public ILInstruction(OpCode opCode, byte[] ilCode, int index, Module manifest) { OpCode = opCode; HasArgument = opCode.OperandType != OperandType.InlineNone; HasSingleByteArgument = OpCodes.TakesSingleByteArgument(opCode); Length = opCode.Size + (HasArgument ? HasSingleByteArgument ? 1 : 4 : 0); if (HasArgument) { if (HasSingleByteArgument) { Argument = ilCode[index + opCode.Size]; } else { Argument = BitConverter.ToInt32(ilCode, index + opCode.Size); } if (OpCode == OpCodes.Ldstr) { Argument = manifest.ResolveString((int)Argument); } else if (OpCode == OpCodes.Call || OpCode == OpCodes.Callvirt) { Argument = manifest.ResolveMethod((int)Argument); } else if (OpCode == OpCodes.Box) { Argument = manifest.ResolveType((int)Argument); } else if (OpCode == OpCodes.Ldfld || OpCode == OpCodes.Ldflda || OpCode == OpCodes.Stfld || OpCode == OpCodes.Ldsfld || OpCode == OpCodes.Stsfld || OpCode == OpCodes.Ldsflda) { Argument = manifest.ResolveField((int)Argument); } else if (OpCode == OpCodes.Newobj) { Argument = manifest.ResolveMethod((int)Argument); } } else { Argument = null; } }
static int GetOperandSizeFromOpCode(OpCode opCode, byte[] msilBits, int currentPosition) { if (OpCodes.TakesSingleByteArgument(opCode)) { return(1); } switch (opCode.OperandType) { case OperandType.InlineSwitch: var jumpAddresses = BitConverter.ToInt32(msilBits, currentPosition + opCode.Size); return(4 + jumpAddresses * 4); case OperandType.InlineI8: case OperandType.InlineR: return(8); case OperandType.InlineBrTarget: case OperandType.InlineField: case OperandType.InlineI: case OperandType.InlineMethod: case OperandType.InlineString: case OperandType.InlineTok: case OperandType.InlineType: case OperandType.ShortInlineR: case OperandType.InlineSig: return(4); case OperandType.InlineVar: return(2); case OperandType.ShortInlineBrTarget: case OperandType.ShortInlineI: case OperandType.ShortInlineVar: return(1); case OperandType.InlineNone: return(0); default: throw new NotImplementedException(); } }
// <Snippet1> public static void Main() { // We need a blank OpCode object for reference when calling FieldInfo.GetValue(). OpCode blankOpCode = new OpCode(); Type myOpCodesType = Type.GetType("System.Reflection.Emit.OpCodes"); FieldInfo[] listOfOpCodes = myOpCodesType.GetFields(); Console.WriteLine("Which OpCodes take single-byte arguments?"); Console.WriteLine("-----------------------------------------"); // Now, let's reflect on each FieldInfo and create an instance of the OpCode it represents. foreach (FieldInfo opCodeFI in listOfOpCodes) { object theOpCode = opCodeFI.GetValue(blankOpCode); Console.WriteLine("{0}: {1}", opCodeFI.Name, OpCodes.TakesSingleByteArgument((OpCode)theOpCode).ToString()); } }
internal void Emit(OpCode opcode, LocalBuilder local) { _ilg.Emit(opcode, local); int tempVal = local.LocalIndex; if (opcode.Equals(OpCodes.Ldloc)) { switch (tempVal) { case 0: opcode = OpCodes.Ldloc_0; break; case 1: opcode = OpCodes.Ldloc_1; break; case 2: opcode = OpCodes.Ldloc_2; break; case 3: opcode = OpCodes.Ldloc_3; break; default: if (tempVal <= 255) { opcode = OpCodes.Ldloc_S; } break; } } else if (opcode.Equals(OpCodes.Stloc)) { switch (tempVal) { case 0: opcode = OpCodes.Stloc_0; break; case 1: opcode = OpCodes.Stloc_1; break; case 2: opcode = OpCodes.Stloc_2; break; case 3: opcode = OpCodes.Stloc_3; break; default: if (tempVal <= 255) { opcode = OpCodes.Stloc_S; } break; } } else if (opcode.Equals(OpCodes.Ldloca)) { if (tempVal <= 255) { opcode = OpCodes.Ldloca_S; } } AdvanceOffset(opcode); if (opcode.OperandType == OperandType.InlineNone) { return; } else if (!OpCodes.TakesSingleByteArgument(opcode)) { _offset += 2; } else { _offset++; } AssertOffsetMatches(); }
/// <inheritdoc/> public IEmitter Emit(OpCode opcode, ILocal local) { this.emitter?.Emit(opcode, local); int localIndex = local.LocalIndex; if (opcode.Equals(OpCodes.Ldloc)) { switch (localIndex) { case 0: opcode = OpCodes.Ldloc_0; break; case 1: opcode = OpCodes.Ldloc_1; break; case 2: opcode = OpCodes.Ldloc_2; break; case 3: opcode = OpCodes.Ldloc_3; break; default: if (localIndex <= 255) { opcode = OpCodes.Ldloc_S; } break; } } else if (opcode.Equals(OpCodes.Stloc)) { switch (localIndex) { case 0: opcode = OpCodes.Stloc_0; break; case 1: opcode = OpCodes.Stloc_1; break; case 2: opcode = OpCodes.Stloc_2; break; case 3: opcode = OpCodes.Stloc_3; break; default: if (localIndex <= 255) { opcode = OpCodes.Stloc_S; } break; } } else if (opcode.Equals(OpCodes.Ldloca) && localIndex <= 255) { opcode = OpCodes.Ldloca_S; } this.OutputOpCode(opcode); this.debugOutput.WriteLine("\t[{0}]", local.Name); this.offset += OpCodes.TakesSingleByteArgument(opcode) ? 1 : 2; return(this); }