// 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;
}
}