/// <summary> /// Realizes a convert instruction. /// </summary> /// <param name="targetType">The target type.</param> /// <param name="instructionFlags">The instruction flags.</param> private void MakeConvert( Type targetType, ILInstructionFlags instructionFlags) { var value = Block.Pop(); var convertFlags = ConvertFlags.None; if (instructionFlags.HasFlags(ILInstructionFlags.Unsigned)) { convertFlags |= ConvertFlags.SourceUnsigned; } if (instructionFlags.HasFlags(ILInstructionFlags.Overflow)) { convertFlags |= ConvertFlags.Overflow; } if (targetType.IsUnsignedInt()) { convertFlags |= ConvertFlags.SourceUnsigned; convertFlags |= ConvertFlags.TargetUnsigned; } var targetTypeNode = Builder.CreateType(targetType); Block.Push(CreateConversion( value, targetTypeNode, convertFlags)); }
/// <summary> /// Constructs a new instruction-flag context. /// </summary> /// <param name="flags">The instruction flags.</param> /// <param name="argument">The flags argument.</param> public ILInstructionFlagsContext( ILInstructionFlags flags, object argument) { Flags = flags; Argument = argument; }
/// <summary> /// Disassembles the current method and returns a list of /// disassembled instructions. /// </summary> /// <returns>The list of disassembled instructions.</returns> public DisassembledMethod Disassemble() { while (ilOffset < il.Length) { instructionOffset = ilOffset; var opCode = ReadOpCode(); if (debugInformationEnumerator.MoveTo(instructionOffset)) { CurrentSequencePoint = debugInformationEnumerator.Current; } if (TryDisassemblePrefix(opCode)) { continue; } if (TryDisasembleInstruction(opCode)) { // Reset flags flags = ILInstructionFlags.None; flagsArgument = null; } else { if (debugInformationEnumerator.TryGetCurrentDebugLocationString( out string debugLocation)) { switch (opCode) { case ILOpCode.Ldftn: throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedILInstructionPossibleLambda, MethodBase.ToString(), opCode, debugLocation)); default: throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedILInstructionDebugLoc, MethodBase.ToString(), opCode, debugLocation)); } } else { throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedILInstruction, MethodBase.ToString(), opCode)); } } } return(new DisassembledMethod( MethodBase, instructions.ToImmutable(), MethodBody.MaxStackSize)); }
/// <summary> /// Realizes a convert instruction. /// </summary> /// <param name="block">The current basic block.</param> /// <param name="builder">The current builder.</param> /// <param name="targetType">The target type.</param> /// <param name="instructionFlags">The instruction flags.</param> private static void MakeConvert( Block block, IRBuilder builder, Type targetType, ILInstructionFlags instructionFlags) { var value = block.Pop(); var convertFlags = ConvertFlags.None; if (instructionFlags.HasFlags(ILInstructionFlags.Unsigned)) { convertFlags |= ConvertFlags.SourceUnsigned; } if (instructionFlags.HasFlags(ILInstructionFlags.Overflow)) { convertFlags |= ConvertFlags.Overflow; } if (targetType.IsUnsignedInt()) { convertFlags |= ConvertFlags.SourceUnsigned; convertFlags |= ConvertFlags.TargetUnsigned; } var type = targetType.GetBasicValueType(); var targetTypeNode = block.Builder.GetPrimitiveType(type); block.Push(CreateConversion( builder, value, targetTypeNode, convertFlags)); }
/// <summary> /// Realizes a compare instruction of the given type. /// </summary> /// <param name="compareKind">The comparison kind.</param> /// <param name="instructionFlags">The instruction flags.</param> private void MakeCompare( CompareKind compareKind, ILInstructionFlags instructionFlags) { var value = CreateCompare(compareKind, instructionFlags); Block.Push(value); }
/// <summary> /// Realizes a compare instruction of the given type. /// </summary> /// <param name="block">The current basic block.</param> /// <param name="builder">The current builder.</param> /// <param name="compareKind">The comparison kind.</param> /// <param name="instructionFlags">The instruction flags.</param> private static void MakeCompare( Block block, IRBuilder builder, CompareKind compareKind, ILInstructionFlags instructionFlags) { var value = CreateCompare(block, builder, compareKind, instructionFlags); block.Push(value); }
/// <summary> /// Creates a compare instruction of the given type. /// </summary> /// <param name="compareKind">The comparison kind.</param> /// <param name="instructionFlags">The instruction flags.</param> private Value CreateCompare( CompareKind compareKind, ILInstructionFlags instructionFlags) { var compareFlags = CompareFlags.None; if (instructionFlags.HasFlags(ILInstructionFlags.Unsigned)) { compareFlags |= CompareFlags.UnsignedOrUnordered; } return(CreateCompare(compareKind, compareFlags)); }
/// <summary> /// Realizes a conditional branch instruction. /// </summary> /// <param name="block">The current basic block.</param> /// <param name="builder">The current builder.</param> /// <param name="compareKind">The comparison type of the condition.</param> /// <param name="instructionFlags">The instruction flags.</param> private static void MakeBranch( Block block, IRBuilder builder, CompareKind compareKind, ILInstructionFlags instructionFlags) { var targets = block.GetBuilderTerminator(2); var condition = CreateCompare(block, builder, compareKind, instructionFlags); builder.CreateConditionalBranch(condition, targets[0], targets[1]); }
/// <summary> /// Creates a compare instruction of the given type. /// </summary> /// <param name="block">The current basic block.</param> /// <param name="builder">The current builder.</param> /// <param name="compareKind">The comparison kind.</param> /// <param name="instructionFlags">The instruction flags.</param> private static Value CreateCompare( Block block, IRBuilder builder, CompareKind compareKind, ILInstructionFlags instructionFlags) { var compareFlags = CompareFlags.None; if (instructionFlags.HasFlags(ILInstructionFlags.Unsigned)) { compareFlags |= CompareFlags.UnsignedOrUnordered; } return(CreateCompare(block, builder, compareKind, compareFlags)); }
/// <summary> /// Realizes a conditional branch instruction. /// </summary> /// <param name="compareKind">The comparison type of the condition.</param> /// <param name="instructionFlags">The instruction flags.</param> private void MakeBranch( CompareKind compareKind, ILInstructionFlags instructionFlags) { var targets = Block.GetBuilderTerminator(2); var condition = CreateCompare(compareKind, instructionFlags); Builder.CreateIfBranch( Location, condition, targets[0], targets[1]); }
/// <summary> /// Appends an instruction to the current instruction list. /// </summary> /// <param name="type">The instruction type.</param> /// <param name="popCount">The number of elements to pop from the stack.</param> /// <param name="pushCount">The number of elements to push onto the stack.</param> /// <param name="additionalFlags">Additional instruction flags.</param> /// <param name="argument">The argument of the instruction.</param> private void AppendInstructionWithFlags( ILInstructionType type, ushort popCount, ushort pushCount, ILInstructionFlags additionalFlags, object argument = null) { // Merge with current flags instructions.Add(new ILInstruction( instructionOffset, type, new ILInstructionFlagsContext(additionalFlags | flags, flagsArgument), popCount, pushCount, argument, CurrentSequencePoint)); }
/// <summary> /// Disassembles the current method and returns a list of /// disassembled instructions. /// </summary> /// <returns>The list of disassembled instructions.</returns> public DisassembledMethod Disassemble() { while (ilOffset < il.Length) { instructionOffset = ilOffset; var opCode = ReadOpCode(); if (debugInformationEnumerator.MoveTo(instructionOffset) && debugInformationEnumerator.Current.IsKnown) { CurrentLocation = debugInformationEnumerator.Current; } if (TryDisassemblePrefix(opCode)) { continue; } if (TryDisasembleInstruction(opCode)) { // Reset flags flags = ILInstructionFlags.None; flagsArgument = null; } else { throw opCode switch { ILOpCode.Ldftn => this.GetNotSupportedException( ErrorMessages.NotSupportedILInstructionPossibleLambda, opCode), _ => this.GetNotSupportedException( ErrorMessages.NotSupportedILInstruction, opCode) }; } } return(new DisassembledMethod( MethodBase, instructions.ToImmutable(), MethodBody.MaxStackSize)); }
/// <summary> /// Disassembles the current method and returns a list of /// disassembled instructions. /// </summary> /// <returns>The list of disassembled instructions.</returns> public DisassembledMethod Disassemble() { while (ilOffset < il.Length) { instructionOffset = ilOffset; var opCode = ReadOpCode(); if (debugInformationEnumerator.MoveTo(instructionOffset)) { CurrentSequencePoint = debugInformationEnumerator.Current; } if (PrefixHandlers.TryGetValue(opCode, out PrefixHandler prefixHandler)) { prefixHandler(this); } else if (OpCodeHandlers.TryGetValue(opCode, out OpCodeHandler opCodeHandler)) { // Handle operation opCodeHandler(this); // Reset flags flags = ILInstructionFlags.None; flagsArgument = null; } else { if (NotSupportedILInstruction == null) { throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedILInstruction, MethodBase.Name, opCode)); } else { NotSupportedILInstruction(this, opCode); } } } return(new DisassembledMethod(MethodBase, instructions, MethodBody.MaxStackSize)); }
/// <summary> /// Returns true if given flags have the other flags set; /// </summary> /// <param name="flags">The current flags.</param> /// <param name="otherFlags">The flags to check.</param> /// <returns>True, if given flags have the other flags set.</returns> public static bool HasFlags( this ILInstructionFlags flags, ILInstructionFlags otherFlags) => (flags & otherFlags) == otherFlags;
/// <summary> /// Adds the given flags to the current instruction flags. /// </summary> /// <param name="flagsToAdd">The flags to be added.</param> private void AddFlags(ILInstructionFlags flagsToAdd) { flags |= flagsToAdd; }
/// <summary> /// Returns true iff current instruction has the given flags. /// </summary> /// <param name="flags">The flags to check.</param> /// <returns>True, iff current instruction has the given flags.</returns> public bool HasFlags(ILInstructionFlags flags) { return((Flags & flags) == flags); }
/// <summary> /// Returns true if current instruction has the given flags. /// </summary> /// <param name="flags">The flags to check.</param> /// <returns>True, if current instruction has the given flags.</returns> public bool HasFlags(ILInstructionFlags flags) => (Flags & flags) == flags;