// dnlib: See LICENSE.txt for more info using System.Collections.Generic; namespace dnlib.DotNet.Emit { /// /// A CIL opcode /// public sealed class OpCode { /// /// The opcode name /// public readonly string Name; /// /// The opcode as a enum /// public readonly Code Code; /// /// Operand type /// public readonly OperandType OperandType; /// /// Flow control info /// public readonly FlowControl FlowControl; /// /// Opcode type /// public readonly OpCodeType OpCodeType; /// /// Push stack behavior /// public readonly StackBehaviour StackBehaviourPush; /// /// Pop stack behavior /// public readonly StackBehaviour StackBehaviourPop; /// /// Gets the value which is compatible with /// public short Value => (short)Code; /// /// Gets the size of the opcode. It's either 1 or 2 bytes. /// public int Size => Code < (Code)0x100 || Code == Code.UNKNOWN1 ? 1 : 2; /// /// Constructs an experimental opcode. /// public OpCode(string name, byte first, byte second, OperandType operandType, FlowControl flowControl, StackBehaviour push, StackBehaviour pop) : this(name, (Code)((first << 8) | second), operandType, flowControl, OpCodeType.Experimental, push, pop, true) { } internal OpCode(string name, Code code, OperandType operandType, FlowControl flowControl, OpCodeType opCodeType, StackBehaviour push, StackBehaviour pop, bool experimental = false) { Name = name; Code = code; OperandType = operandType; FlowControl = flowControl; OpCodeType = opCodeType; StackBehaviourPush = push; StackBehaviourPop = pop; if (!experimental) { if (((ushort)code >> 8) == 0) OpCodes.OneByteOpCodes[(byte)code] = this; else if (((ushort)code >> 8) == 0xFE) OpCodes.TwoByteOpCodes[(byte)code] = this; } } /// /// Creates a new instruction with no operand /// /// A new instance public Instruction ToInstruction() => Instruction.Create(this); /// /// Creates a new instruction with a operand /// /// The value /// A new instance public Instruction ToInstruction(byte value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance public Instruction ToInstruction(sbyte value) => Instruction.Create(this, value); /// /// Creates a new instruction with an operand /// /// The value /// A new instance public Instruction ToInstruction(int value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance public Instruction ToInstruction(long value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance public Instruction ToInstruction(float value) => Instruction.Create(this, value); /// /// Creates a new instruction with a operand /// /// The value /// A new instance public Instruction ToInstruction(double value) => Instruction.Create(this, value); /// /// Creates a new instruction with a string operand /// /// The string /// A new instance public Instruction ToInstruction(string s) => Instruction.Create(this, s); /// /// Creates a new instruction with an instruction target operand /// /// Target instruction /// A new instance public Instruction ToInstruction(Instruction target) => Instruction.Create(this, target); /// /// Creates a new instruction with an instruction target list operand /// /// The targets /// A new instance public Instruction ToInstruction(IList targets) => Instruction.Create(this, targets); /// /// Creates a new instruction with a type operand /// /// The type /// A new instance public Instruction ToInstruction(ITypeDefOrRef type) => Instruction.Create(this, type); /// /// Creates a new instruction with a type operand /// /// The type /// A new instance public Instruction ToInstruction(CorLibTypeSig type) => Instruction.Create(this, type.TypeDefOrRef); /// /// Creates a new instruction with a method/field operand /// /// The method/field /// A new instance public Instruction ToInstruction(MemberRef mr) => Instruction.Create(this, mr); /// /// Creates a new instruction with a field operand /// /// The field /// A new instance public Instruction ToInstruction(IField field) => Instruction.Create(this, field); /// /// Creates a new instruction with a method operand /// /// The method /// A new instance public Instruction ToInstruction(IMethod method) => Instruction.Create(this, method); /// /// Creates a new instruction with a token operand /// /// The token /// A new instance public Instruction ToInstruction(ITokenOperand token) => Instruction.Create(this, token); /// /// Creates a new instruction with a method signature operand /// /// The method signature /// A new instance public Instruction ToInstruction(MethodSig methodSig) => Instruction.Create(this, methodSig); /// /// Creates a new instruction with a method parameter operand /// /// The method parameter /// A new instance public Instruction ToInstruction(Parameter parameter) => Instruction.Create(this, parameter); /// /// Creates a new instruction with a method local operand /// /// The method local /// A new instance public Instruction ToInstruction(Local local) => Instruction.Create(this, local); /// public override string ToString() => Name; } }